서론
언제나 그렇듯 아래와 같이 Delegate를 만들고 있었습니다.
protocol OOODelegate: AnyObject {
func ...
}
근데 아차! 싶었습니다.
Delegate에 왜 AnyObject를 붙여야 하지?라는 생각을 따로 안 해봤더라고요.
어렴풋이 알고는 있었지만 따로 생각을 해보거나 글로 정리한 적이 없어서
이렇게 포스팅하기로 결정했습니다.
iOS에서는 언제 Delegate를 쓸까?
Delegate는 Delegate를 채택하는 누군가에게 나의 행위를 위임합니다.
Delegate를 사용하는 곳에서는 메서드를 호출만 하고, Delegate를 채택하는 곳에서 메서드를 구현하는 것입니다.
iOS에서는 주로 유저 이벤트에 따른 행위를 구현할 때 Delegate를 사용합니다.
예를 들어, UICollectionView의 didSelectRowAt는 UICollectionViewCell을 유저가 클릭할 때의 동작을 구현하는 거예요.
Cell을 클릭할 때의 동작은 앱마다, 화면마다, View마다 다르기 때문에 사용하는 쪽에게 구현을 위임하는 것입니다.
AnyObject는 필수일까?
결론은 Delegate 패턴에 AnyObject는 필수가 아닙니다.
하지만 iOS에서는 거의 필수입니다.
강한 순환 참조 때문입니다.
위에서 말했듯이 iOS에서는 View(또는 VC)와 View(또는 VC) 사이에 Delegate가 사용됩니다.
UIView는 클래스 타입이고 두 개의 클래스 타입이 strong 참조로 엮이면 강한 순환 참조가 발생합니다.
강한 순환 참조가 발생하면 메모리 leak이 발생하게 되기 때문에 이를 끊어줘야 하는데요.
그 방법 중 하나는 weak 키워드를 붙이는 것입니다.
그런데 weak 키워드는 클래스 타입만 사용이 가능합니다.
일반적으로 "참조"는 클래스 타입에서만 발생하기 때문입니다. (물론 일부 예외는 있지만요.)
만약 AnyObject를 채택하지 않고 weak를 사용하면
'weak' must not be applied to non-class-bound ~~~
라는 컴파일 에러가 발생하기까지 합니다.
그래서 weak를 사용하기 위해서는 AnyObject를 채택해야 하는 거죠.
마무리
이제 Delegate에 AnyObject를 붙이는 이유를 아시겠나요?
Delegate에 AnyObject가 필수인 건 당연하지 않다고 생각합니다.
Delegate 패턴은 언어에 의존적이지 않으므로 다른 언어에서도 얼마든지 쓰일 수 있기 때문입니다.
그래서 AnyObject를 붙이는 것을 당연하게 여기는 게 아니라
Swift의 강한 순환 참조 특성 때문에 AnyObject를 붙여야 하는구나!라고 생각하면 좋겠는 마음입니다 ㅎㅎ
감사합니다.
아직은 초보 개발자입니다.
더 효율적인 코드 훈수 환영합니다!
공감과 댓글 부탁드립니다.