티스토리 뷰
반응형
# 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
반응형
'🍏 > 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
TAG
- Django Heroku Scheduler
- cocoapod
- 장고 URL querystring
- 장고 Custom Management Command
- flutter build mode
- Python Type Hint
- ipad multitasking
- Flutter getter setter
- DRF APIException
- 플러터 싱글톤
- PencilKit
- flutter 앱 출시
- 플러터 얼럿
- ribs
- flutter dynamic link
- Flutter Text Gradient
- Flutter 로딩
- Watch App for iOS App vs Watch App
- METAL
- Sketch 누끼
- Flutter Spacer
- Django Firebase Cloud Messaging
- drf custom error
- Django FCM
- github actions
- flutter deep link
- Flutter Clipboard
- Dart Factory
- 구글 Geocoding API
- SerializerMethodField
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 29 | 30 | 31 |
글 보관함