티스토리 뷰
# self in a clousre
다음과 같은 경우 Strong Reference Cycle (Retain Cycle) 이 발생한다.
class SomeViewController: UIViewController {
var someClosure: (() -> Void)?
deinit {
print("deinit")
}
override func viewDidLoad() {
super.viewDidLoad()
self.someClosure = {
print(self)
}
}
}
그래서 클로져 캡쳐리스트를 작성한다.
class SomeViewController: UIViewController {
var someClosure: (() -> Void)?
deinit {
print("deinit")
}
override func viewDidLoad() {
super.viewDidLoad()
self.someClosure = { [weak self] in
print(self)
}
}
}
# self in a closure in a closure
그렇다면 클로저 안의 클로저는 어떨까? 여기도 클로저 캡쳐리스트를 작성해줘야할까?
결론은 아래와 같다.
Only declaring weak or unowned self in the capture list of the outer closure is enough to avoid retain cycles
if you don't create a strong reference to self within the outer closure (e.g. by doing: guard let strongSelf = self
else { return }).
1️⃣
outer closure에서 strong capture를 하지 않았기 때문에 inner closure는 안해줘도 된다.
(the weakly captured self is still available in the inner closure)
deinit 이 호출된다.
class SomeViewController: UIViewController {
var someClosure: (() -> Void)?
var innerClosure: (() -> Void)?
deinit {
print("deinit")
}
override func viewDidLoad() {
super.viewDidLoad()
self.someClosure = { [weak self] in
print(self)
self?.innerClosure = {
print(self)
}
}
self.someClosure?() // innerClosure 에 값이 들어가야하니까 호출함.
}
}
2️⃣
하지만 outer closure 내에서 strong capture를 하는 경우에는 inner closure 에도 클로져 캡쳐리스트를 작성해줘야한다.
deinit 이 호출되지 않는다.
class SomeViewController: UIViewController {
var someClosure: (() -> Void)?
var innerClosure: (() -> Void)?
deinit {
print("deinit")
}
override func viewDidLoad() {
super.viewDidLoad()
self.someClosure = { [weak self] in
✅ guard let self else { return }
print(self)
self.innerClosure = {
print(self)
}
}
self.someClosure?() // innerClosure 에 값이 들어가야하니까 호출함.
}
}
inner closure 에도 클로져 캡쳐리스트를 작성해주면
deinit이 호출된다.
class SomeViewController: UIViewController {
var someClosure: (() -> Void)?
var innerClosure: (() -> Void)?
deinit {
print("deinit")
}
override func viewDidLoad() {
super.viewDidLoad()
self.someClosure = { [weak self] in
guard let self else { return }
print(self)
self.innerClosure = { ✅ [weak self] in
print(self)
}
}
self.someClosure?() // innerClosure 에 값이 들어가야하니까 호출함.
}
}
[ Reference ]
https://stackoverflow.com/questions/37837862/unowned-self-in-a-closure-in-a-closure
Unowned self in a closure in a closure
If I have a closure in another closure is it enough to use unowned/weak once in the outer closure to avoid retain cycles? Example: foo.aClosure({[unowned self] (allowed: Bool) in if a...
stackoverflow.com
'🍏 > Swift' 카테고리의 다른 글
[Swift] RandomAccessCollection / BidirectionalCollection 의 Time Complexity (0) | 2023.09.23 |
---|---|
[Swift] Continuations > completion or delegate 를 async 로 (0) | 2023.08.02 |
[Swift Collections] Heap (0) | 2023.05.20 |
[Swift] Dictionary 의 subscript 3개 / KeyValuePairs (0) | 2023.04.29 |
[Swift] actor (0) | 2023.04.10 |
- Total
- Today
- Yesterday
- flutter dynamic link
- Dart Factory
- Flutter getter setter
- 플러터 얼럿
- Django Heroku Scheduler
- flutter 앱 출시
- Flutter 로딩
- 장고 URL querystring
- Sketch 누끼
- Watch App for iOS App vs Watch App
- Flutter Clipboard
- Python Type Hint
- DRF APIException
- PencilKit
- github actions
- 구글 Geocoding API
- Flutter Spacer
- cocoapod
- ribs
- SerializerMethodField
- ipad multitasking
- 장고 Custom Management Command
- flutter build mode
- 플러터 싱글톤
- METAL
- Django Firebase Cloud Messaging
- drf custom error
- Flutter Text Gradient
- flutter deep link
- Django FCM
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |