📌 위임(delegation)
클래스 또는 구조체가 자신의 책임 중 일부를 다른 유형의 인스턴스에 넘겨줄 수 있도록 하는 설계 패턴.
핵심 목적은 객체가 분리된 방식(의존성 감소)으로 소유자와 다시 통신할 수 있도록 하는 것!
객체 소유자의 구체적인 유형을 알 필요가 없으므로 재사용 및 유지관리가 훨씬 쉬운 코드를 작성할 수 있다!
나는 이벤트 받은 객체와 이벤트 처리하는 객체가 다른 경우, 두 객체가 소통하도록 델리게이트 패턴을 쓴다. 이를 통해 객체들의 역할과 책임을 나눠서 객체들은 서로 요청/응답만 하는 과정을 거치고, 의존성을 낮출 수 있도록 하는 것이라고 생각한다.
어떤 데이터를 사용자 이벤트로 입력받고, 그 값을 가지고 어떤 작업을 해야 하는데 이 작업은 나(class 객체)에서 하는 게 아니라 다른 놈(class 객체)이 해줘야 하는 작업이라면? 혹은 그 작업을 넘기고 싶다면?^^ delegate! 그 일을 위임해 준다! 여기서 값을 받은 건 나! 이므로 입력받은 데이터도 함께 넘겨주면~ 그 값에 맞춰서 작업을 해주겠지!
델리게이트 프로토콜을 하나 만들고, 그 안에는 메소드를 정의해 준다.
→ 프로토콜에는 어떤 구현을 하는 게 아니라 정의만 해준다!
→ 프로토콜을 사용하면 class는 물론 상속이 불가한 struct, enum에서도 이를 받아서 사용할 수 있다!
예제를 직접 만들어보면 이해하기 더 쉽다!
간단하게 예제를 만들어봤는데, next 버튼을 눌러서 사용자 이벤트를 받을 VC(secondVC)로 화면 전환을 해줬다. secondVC에서 Change Label 버튼을 클릭하면 Label이 변경된다.
import UIKit
class FirstViewController: UIViewController, EventDelegate {
@IBOutlet weak var label: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func tapNextButton(_ sender: Any) {
guard let secondVC = storyboard?.instantiateViewController(withIdentifier: "secondVC") as? SecondViewController else { return }
secondVC.delegate = self //secondVC의 위임자는 나야!
self.present(secondVC, animated: true)
}
func changeLabel(_ txt: String) {
label.text = txt
}
}
protocol EventDelegate: AnyObject {
func changeLabel(_ txt: String)
}
class SecondViewController: UIViewController {
@IBOutlet weak var changeButton: UIButton!
weak var delegate: EventDelegate?
override func viewDidLoad() {
super.viewDidLoad()
changeButton.layer.cornerRadius = 10
}
@IBAction func tapChangeLabelButton(_ sender: Any) {
delegate?.changeLabel("hello🪄\nthis is nyeong!🐬")
self.dismiss(animated: true)
}
}
- FirstViewController: 이벤트를 통해 받은 입력값을 위임해서 처리 + 화면에 보여주기 → 이벤트를 처리하는 객체
- SecondViewController: 사용자로부터 이벤트를 받아서 위임자에게 넘기기 → protocol 생성 → 이벤트를 받는 객체
🚨 주의할 점!
delegate 프로퍼티를 정의할 때, weak 약한 참조를 사용해서 선언했다. 두 클래스를 델리게이트로 연결하면 강한 참조 순환이 발생할 수 있기 때문! → delegate 프로퍼티를 통해 상대 클래스 객체를 강하게 참조하고, delegate 역시 강하게 참조하고 있기 때문. 약한 참조를 사용하면 시스템에서 메모리에서 해제시킬 수 있기 때문에 강한 참조 순환이 풀린다.
'iOS' 카테고리의 다른 글
[iOS/UIKit] 코드베이스로 커스텀 객체 만들기! (Custom UIView) (0) | 2023.03.17 |
---|---|
[iOS/UIKit] 화면 전환에 대해 알아보자! (0) | 2023.03.14 |
[iOS] View Life Cycle을 알아보자! (0) | 2023.02.21 |
[iOS] App Life Cycle을 알아보자! (0) | 2023.02.21 |
[iOS] AutoLayout 정복하기 - Constraints (0) | 2023.02.13 |