Delegate? retain이 될까?

marisol👩🏻‍💻·2022년 8월 11일
1

1주차 스터디에서 공부했던 "Delegate란 무엇인지 설명하고, Retain이 되는지 안되는지 그 이유를 함께 설명하시오"라는 주제 정리하기🤓


📌 Delegate? retain이 될까?

Deletate은 "대리자, 위임하다"라는 단어의 뜻처럼
하나의 객체가 모든 일을 처리하는 것이 아니라, 처리해야할 일 중 일부를 다른 객체에 넘기는 것을 말합니다.
위임된 책임을 캡슐화하는 프로토콜로 구현되며, 위임자가 위임된 기능을 제공하도록 보장합니다.
Delegate을 통해 일을 위임하는 객체들은 일을 시킬 뿐, 일이 어떻게 처리되는지 모르기 때문에 코드의 유지보수 측면에서 장점을 갖고 있습니다.

retain은 객체가 메모리에서 해제되지 않도록 호출되어 레퍼런스 카운트를 증가시키는데,
delegate은 객체끼리 참조값을 사용하기 때문에 retain이 됩니다.

메모리 누수를 방지하기 위해 프로토콜이 AnyObject를 채택하여 class에서만 해당 프로토콜을 채택할 수 있도록 만들어주고, delegatedmf weak으로 선언하여 사용합니다.

📌 메모리 누수는 어떻게 발생할까?

swift는 ARC를 활용해서 자동으로 앱의 메모리 사용을 추적하고 관리해주는데요,
두 인스턴스가 서로 강하게 참조하고 있을 때 RC가 0이 아니기 때문에 참조 해제가 불가능한 상황에서 메모리 누수가 발생합니다.
필요하지 않은 메모리를 계속 점유하고 있게 되기 때문에 메모리 사용량이 증가합니다.

📌 메모리 누수를 방지하는 방법 중 weak과 unowned는 어떤 차이가 있을까?

weak과 unowned 모두 RC를 증가시키지 않는다는 공통점이 있습니다.

weak은 말 그대로 약한 참조이며, A와 B가 서로를 참조한다고 할 때, A 인스턴스의 수명이 더 짧아 먼저 할당해제할 수 있을 때 B가 A를 약하게 참조합니다.
참조하는 인스턴스가 메모리에서 해제되면 자동으로 weak 참조를 nil로 설정합니다.
이렇게 런타임에 값이 nil로 변경될 수 있기 때문에 weak 참조 인스턴스는 항상 Optional과 var로 선언되어야 합니다.
(예: 아파트에 입주민이 없는 경우가 있다고 할 수 있을 때, Apartment가 약한 참조로 Person 인스턴스 프로퍼티를 갖습니다.)

unowned는 weak 참조와 달리, unowned로 선언된 프로퍼티가 항상 값을 가질 것으로 예상합니다.
그래서 optional이 아니며, 메모리에 없는 값에 접근하려고 하면 crash를 발생시킬 수 있습니다.
항상 값을 가질 것으로 예상되기 때문에 다른 인스턴스의 수명과 동일하거나, unowned로 선언된 프로퍼티의 수명이 더 길다고 확신할 수 있는 경우에만 사용해야 합니다.
또한 런타임에 nil이 될 일이 없기 때문에 let으로도 선언 가능합니다.
(예: 신용카드인 CreditCard보다 고객인 Customer가 먼저 없어지는 경우는 없을 것이라고 확신할 수 있을 때 CreditCard 내에서 Customer를 unowned로 선언할 수 있습니다.)

📌 Delegate에 struct를 사용하면 안될까?

구조체는 값 타입이기 때문에 할당할 때 포인터를 넘겨받는 것이 아니라 값이 복사되는데요,
textField.delegate = self와 같이 일을 넘겨받아 처리할 위임자를 지정해주는 과정에서 주소값을 넘겨주는 것이 아니라 값을 넘겨주는 것이기 때문에 구조체를 delegate으로 선언하는 것은 적절하지 않습니다.
그래서 프로토콜을 클래스만 채택할 수 있도록 AnyObject를 채택하고, 메모리 누수가 발생하지 않도록 delegate을 weak으로 선언해주어야 합니다.

0개의 댓글