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