2022. 1. 16. 22:50ㆍProgramming/iOS_Swift
Delegate Pattern을 이해하기 위해서는 반드시 프로토콜에 대한 학습이 선행되어야 한다. 프로토콜을 먼저 학습하고 읽을 것을 권장한다.
https://daltonic.tistory.com/31
Delegate Pattern 이란?
델리게이트 패턴(위임 패턴)이란 디자인 패턴으로 어떤 객체(클래스의 인스턴스)가 자신이 가지고 있는 일들 중 일부분을 다른 객체에게 위임하여 처리시키는 패턴을 말한다. 조금 안 와닿을 수 있는데, 속된 말로 짬 때린다(?)라고 이해하면 편할 것 같다. 쉽고 편한 이해를 위해 델리게이트 패턴을 적용시켜서 어떻게 짬을 때리는지 보자!
우선 어떤 일을 시킬 건지 프로토콜을 만들어줬다.
소대장 대신 팀의 건강을 체크하고 훈련을 시킬 예정이다.
다음으로 팀멤버뷰컨트롤러와 소대장뷰컨트롤러를 만들어줬다.
먼저 팀원뷰컨트롤러 코드를 살펴보면, 소대장의 일거리 리스트 프로토콜을 채택한 걸 확인할 수 있다. 즉, 소대장의 일들을 얘네가 대신 처리해주는 것이다. 팀원의 건강을 체크하는 메서드와 하드트레이닝 메서드를 소대장 대신 가지고 있다. 테스트를 위해 버튼을 하나 만들어줬고 버튼을 클릭하면 소대장 뷰컨트롤러로 넘어간다.
소대장 뷰컨트롤러를 보면 약한참조를 한 delegate라는 변수에 소대장 일 리스트 프로토콜 타입을 선언했다. 여기서 이 delegate라는 변수가 잘 이해가 안 갈 수 있는데, 먼저 약한참조를 해준 이유는 순환참조가 일어나 메모리 누수가 발생하는 경우를 예방하기 위해서이다(참고: 강한참조/약한참조 https://daltonic.tistory.com/27) 해당 변수를 만들어준 이유는 누가 소대장 뷰컨트롤러 객체의 어떤 일을 대신할지 정해주기 위해서이다. 코드를 보면 버튼이 클릭됐을 때, 소대장 일 리스트 중에서 팀의 건강체크를 대신 처리하게끔 해줬다.
그러면, 누가 어떤 일을 대신할지 정해주기 위해 delegate이라는 변수를 만들었는데, 누가 할지는 어디서 결정될까.
잠시 팀멤버 뷰컨트롤러의 코드를 다시보자.
팀멤버 뷰컨트롤러를 보면 버튼이 클릭됐을 때, 소대장 뷰컨트롤러 인스턴스의 delegate 변수에다가 팀멤버뷰컨트롤러 본인을 지정했음을 확인할 수 있다. 분명 프로토콜과 팀멤버뷰컨트롤러의 타입이 서로 안맞는게 맞지만 팀멤버 뷰컨트롤러가 같은 프로토콜을 준수(conform)하고 구현하게 됐기에, 준수하고 있는 프로토콜로 형변환이 가능해진다. 정리하면, 팀멤버뷰컨트롤러 객체가 소대장뷰컨트롤러 객체의 일 리스트(프로토콜)를 대신 자신이 처리하겠다고 지정해준 것이다!
코드의 이해는 끝났으니, 실제로 구현이 어떻게 기능하는지 확인해보자.
최초 팀멤버 뷰컨트롤러 화면에서 이동버튼을 누르고 소대장 뷰컨트롤러로 넘어갔다. 다음 소대장 뷰컨트롤러에서 '내 일을 대신처리해줘' 버튼을 누르고 로그를 확인해보면, 정상적으로 팀멤버뷰컨트롤러의 메서드가 실행되고 있음을 확인할 수 있다. 즉, 짬 때리는데에 성공했다!
왜 쓸까?
1. 클래스의 확장성과 범용성을 늘려준다.
만약 누군가에게 위임하지 않고 클래스 내에서 모든 일들을 처리한다면, 클래스는 너무 방대해질 수 있고 가독성이 떨어질 수 있다. 이럴 때 Delegate 패턴을 활용함으로써, 어떤 클래스가 담당하고 있는 일들의 일부를 다른 클래스에서 처리하게끔 만들어주고 클래스 간 원활한 데이터교환이 이뤄지게 만들어 줄 수 있다.
2. 코드의 재사용성이 좋아지고 관리가 용이해진다.
예를 들어, 이런 경우가 있다고 가정해보자. 어떤 테이블뷰가 있고 각 셀에는 버튼이 하나씩 담겨있다. 이때, 셀을 클릭하는 것이 아니라 셀 내의 버튼을 클릭했을 때, 어떤 이벤트를 전달한다고 해보자. 해당 이벤트는 버튼이 몇 번째 셀에 있었는지에 따라서 다르게 처리된다. 이런 경우, 버튼에 델리게이트 패턴을 구현한다면 몇 번째 셀인지 손쉽게 확인할 수 있고 해당하는 셀에 맞게끔 이벤트를 구현해줄 수 있다.
** 왜 쓸까? 부분은 현재까지 제가 느낀 사견이기 때문에, 틀릴 수도 있습니다. 내용이 잘못됐다면 언제든 지적해주세요!
'Programming > iOS_Swift' 카테고리의 다른 글
[iOS_Swift] Swift Attributes - discardableResult, frozen에 대하여 (0) | 2022.01.23 |
---|---|
[iOS_Swift] deinit이 호출되지 않는 이유 (0) | 2022.01.19 |
[iOS_Swift] Properties - 연산 프로퍼티(Computed Property) (0) | 2022.01.13 |
[iOS_Swift] 프로토콜(Protocol) (1) - Property Requirements (0) | 2022.01.10 |
[iOS_Swift] 옵셔널(Optional) 제대로 이해하기 (0) | 2022.01.05 |