iOS/Swift - ARC에 대해 (3)

2895 단어 swiftiOSARCARC

클로저 내에서 발생하는 Strong Reference Cycle 해결하기


이런 문제를 해결하기 위해서 클로저 내에서 “capture list”를 정의한다.

capture list는 클로저 바디 내에서 다른 reference type (i.e class) 에 접근할 때 어떤 규칙을 가지고 접근할지 정의하는 것이다.

클로저 내에서 self를 캡쳐하면 그 default가 strong reference이기 때문에 weak로 명시해줘야 reference cycle이 일어나지 않는다.

💡 **클로저 내에서 self를 쓰는 이유는?** (ex. self.someProperty() )

self를 모르고 capture 할 것을 대비해서 Swift가 기본적으로 요구한다. 그래야 retain cycle이 일어날 수 있음을 사전에 인지하기 때문이다.

Capture List 정의하기


Capture “List”이기 때문에 배열과 비슷한 형태로 정의한다

lazy var someClosure = {
    [unowned self, weak delegate = self.delegate] (index: Int, stringToProcess: String) -> String in
    // closure body goes here
}

만약 클로저 내에서 쓰는 파라미터가 없거나 리턴 타입이 없으면 “in” keyword를 붙여줘야함

lazy var someClosure = {
    [unowned self, weak delegate = self.delegate] in
    // closure body goes here
}

→ weak 으로 하면 옵셔널이기 때문에 클로저 내에서 self가 존재하는지 안 하는지 한 번 안전하게 확인을 할 수가 있게된다.

→ unowned는 self가 확실히 있을 때만 쓰자

✻ 위에서 정의했던 HTMLElement 클래스의 asHTML 프러퍼티 같은 경우에는 클로저 내에서 weak self 보다 unowned라고 하는게 더 적합할거다. 왜냐하면 HTMLELement인스턴스가 없으면 애초에 asHTML()이 불릴 일이 없는게 확실하기 때문이다.

좋은 웹페이지 즐겨찾기