weak self(2회독)_다시

hankyulee·2021년 10월 3일
0

closure

목록 보기
7/7


클래스 내에서 저장프로퍼티에 할당된 클로저가 있고 self 를 참조할경우 reference counter가 하나 더 증가하므로 controller에서 dismiss하더라도 class 가 deinit되지 않는다. 따라서 다음과 같이 약한 참조를 이용하여 dismiss될 때 메모리에서 해제될 수 있도록 한다.

이제 deinit된다.
참고로 처음에 [weak self] vm in ...
이렇게 클로저 내부의 함수의 클로저에 약한 참조를 붙여봤지만, deinit되지 않음을 확인했다.
또한 self.t = vm 하지 않으면 생성된 vm 인스턴스는 deinit된다. 즉 프로퍼티에 저장하지 않으면 deinit된다.

비슷하게 위와같이 self.accidents.append 하여 인스턴스를 저장하고 있으면 deinit되지 않는다. 또한 기존에는 [weak self] vm in .. 했는데, 프로퍼티에 클로저를 포함하고있는 함수를 저장하는 것이 아니므로 weak self가 필요없음을 알게되었다. 이는 break point를 이용해서 해당 뷰컨트롤러를 빠져나올때 메모리에서 해제되는지 확인실험을 통해 알게되었다.

뷰컨트롤러가 메모리에서 해제되지않을 경우 어떤 메모리 손실이 있나 간접적으로 실험해보았다.

뷰컨트롤러 클래스안에 위의 인스턴스를 두개 만들어서 저장했다. 그리고 weak self 를 붙이지 않고 뷰컨트롤러를 메모리에서 해제되지 못하게 했을때 뷰컨트롤러를 dismiss했음에도 deinit되지않아 두개의 인스턴스 역시 deinit을 출력하지 않았다. weak self를 첨가했을 때는 deinit을 두번 출력하였다.
결론: 클로저 역시 참조타입이므로 서로를 참조할 경우 retain cycle이 발생하니까 약한 참조를 하자.. 단 프로퍼티에 저장하지 않을 경우는 retain cycle 발생하지 않으니까 신경쓰지 않아도된다.

다음과 같이 IBAction에서 [weak self] 하지 않아도 된다. 일반 함수면 weak self 해줘야하지만(저장 프로퍼티에서 그랬듯이), IBAction func은 안해도된다. deinit확인했다.

다음과 같이 일반함수이면 weak self 해줘야한다.

0개의 댓글