Closure 에서 뭘 쓰는게 맞는건가 하는 논란?이 많습니다. ( 그냥 제가 잘 몰랐습니다...)
논란의 글...
어쨌든 둘다 순환참조를 막기 위해서 쓰긴 써야겠는데...
다행이 공식 문서에 어느정도 설명이 되어 있습니다.
문서를 보면... 아래와 같은 글이 있습니다.
요약?하면 unowned reference 는 클로저와 클로저가 사용된 인스턴스 ([unowned self] 라면 클로저와 self 가 되겠죠) 가 서로를 참조하고 동시에 할당이 해제됩니다.
반대로 weak reference 는 참조가 미래 어떤 시점에 해지된다(nil 이된다) 라고 했을때 사용합니다. 이렇게 하면 클로저 안에 있는 값들을 체크할 수 있죠. (nil인지 아닌지, 메모리에 있으면 실행 아니면 return 을 하는..)
사용 예가 있습니다.
lazy var someClosure: () -> String = {
[unowned self, weak delegate = self.delegate!] in
// closure body goes here
}
Swift
복사
클로저가 실행되는 self 는 nil이 될 수 없죠. self가 메모리에서 해지되면 이 클로저도 메모리에서 같이 해제되면 됩니다.
but, delegate 는 보통 외부에서 선언되기 때문에 self 에 비해 독립적이며, someClousure 라는 변수에 접근 할 수 없어도 클로저 내부는 여전히 참조될 수 있습니다.
이 경우엔 weak 를 써서 weak 으로 선언된 변수가 nil 인지 확인해야 한다는 겁니다.
즉 결론을 내면,
self 처럼 클로저를 사용하는 변수(var someClosure)와 수명을 같이 하는 경우엔 unowned,
delegate 처럼 독립적으로 사용되는 값을 클로저에서 참조할 경우엔 weak
•
다른 class 를 참조할 경우에도 weak 을 사용해야...
하지만,
클로저를 사용하는 이유 중 대부분은 아마 네트워크 쪽이 연관되어 있는 경우 일텐데,
unowned 를 쓸 경우 response 를 받는 시점이 화면을 벗어난 시점 일 수 있습니다.
그럼 weak self 를 쓰는게 더 안정적일 껍니다.
그렇다는 건, 상황에 따라 unowned 와 weak 을 구분해 쓰는건데....
실제 코딩하면서 이런 부분들을 다 고려하긴 좀 무리가 있죠 ;)
그래서 그냥 [weak self] 로 쓰고 strongSelf 를 구현하는게 마음 편합니다. ㅎ
lazy var someClosure: () -> String = {
[weak self] in
guard let strongSelf = self else { return }
// closure body goes here
}
Swift
복사
strongSelf 가 너무 길다구요? 그럼 sself 는 어떠신가요? ㅎ