본문 바로가기
프로그래밍 놀이터/iOS

[Effective Objective-C] #40 블록이 자신을 소유한 객체를 다시 소유함으로써 발생하는 리테인 순환을 조심하라

by 돼지왕 왕돼지 2017. 10. 4.
반응형

 [Effective Objective-C] #40 블록이 자신을 소유한 객체를 다시 소유함으로써 발생하는 리테인 순환을 조심하라


출처 : Effective Objective-C

block retain cycle, block weak, nil, weak, [Effective Objective-C] #40 블록이 자신을 소유한 객체를 다시 소유함으로써 발생하는 리테인 순환을 조심하라, 객체 참조, 리테일 순환, 메모리 누수, 블록 리테인 순환, 완료 핸들러 실행, 전가, 참조 nil


-

블록을 주의 깊게 사용하지 않으면 리테인 순환이 쉽게 발생한다.



-

완료 핸들러 블록은 리테인 순환이 발생할 수 있는 참조를 nil 로 만들어 주어야 한다.



-

이 리테인 순환 문제는 완료 콜백 블록을 사용하는 API 에서 흔히 발생하는 것이다.

그렇기 때문에 꼭 알고 있어야 한다.

이 문제는 적절한 순간에 참조 중 하나를 제거함으로써 풀 수 있다.

그러나 항상 참조를 제거할 수 있는 순간이 온다고 보장할 수 없다.

예를 들어 리테인 순환은 오직 완료 핸들러가 동작할 때만 깨질 수 있다.

완료 핸들러가 실행되지 않으면 리테인 순환이 결코 깨지지 않는다.

그리고 누수가 발생할 것이다.



-

리테인 순환이 발생할 수 있는 또 다른 곳은 완료 핸들러 블록 방식을 사용하는 곳이다.

이 리테인 순환은 완료 핸들러 블록이 블록을 소유하는 객체를 참조할 때 발생한다.



-

완료 핸들러를 public 이라고 사용자에게 말하는 순간 캡슐화가 깨질 것이다.

이 경우 리테인 순환을 합리적으로 제거하는 유일한 방법은 사용자가 핸들러를 잡고 있는 프로퍼티를 스스로 해제하는 것이다.

하지만 이 또한 합리적이지 않다.

사용자가 이렇게 하리라고 가정할 수 없기 때문이다.

사용자들은 누수가 생기는 것에 대해 여러분을 비난할 것이다.



-

핵심은 블록이 잡을 수 있는 가능성이 있는 객체가 무엇인지 생각해 보는 것이다.

객체를 잡으면 리테인되기 때문이다.

이런 블록을 잡은 객체들 중에 직간접적으로 다시 블록에 의해 리테인된 객체가 있으면 반드시 이 리테인 순환을 깨뜨릴 방법과 깨뜨릴 시점을 생각해야 한다.




기억할 점


-

블록에 잡힌 객체가 직간접적으로 다시 그 블록을 리테인할 때 발생하는 리테인 순환을 조심하라.


-

특정 시점에서 반드시 리테인 순환이 깨질 것이라는 점을 보장하라.

여러분의 API 사용자에게 이 책임을 전가하면 안 된다.




반응형

댓글