[Swift] delegate 패턴

팔랑이·2024년 7월 7일

iOS/Swift

목록 보기
42/90

개념

한 객체가 해야 할 일을 다른 객체에게 위임하는 패턴. 프로토콜로 "무엇을 위임할 것인가"를 명세하고, 위임받은 객체가 이를 구현한다.

  • Delegator (주체): 작업을 위임하는 쪽. delegate 프로퍼티를 들고 있음.
  • Delegate (객체): 위임받아 실제로 처리하는 쪽. 프로토콜을 채택하고 구현함.

구현 순서

1. 프로토콜 정의

위임할 동작을 프로토콜로 명세.

protocol ButtonDelegate: AnyObject {
    func didTapButton()
}

AnyObject 채택은 weak 참조를 가능하게 하기 위함 → 순환 참조 방지 (7/8 ARC 내용과 연결).

2. 주체(Delegator) 정의

delegate 프로퍼티를 weak var로 선언하고, 이벤트 발생 시 호출.

class Button {
    weak var delegate: ButtonDelegate?

    func tap() {
        delegate?.didTapButton()
    }
}

3. Delegate 구현

프로토콜을 채택하고, 자신을 delegate로 등록.

class ViewController: ButtonDelegate {
    let button = Button()

    init() {
        button.delegate = self  // 자신을 위임 객체로 등록
    }

    func didTapButton() {
        print("Button was tapped!")
    }
}

let vc = ViewController()
vc.button.tap()  // "Button was tapped!"

왜 weak var인가

Buttondelegate를 강하게 참조하고, ViewControllerButton을 강하게 참조하면 순환 참조 발생 → 둘 다 메모리에서 해제 안 됨.

weak var delegate로 선언하면 RC를 증가시키지 않아서 순환 참조가 끊김.

핵심 가치

직접 참조 대신 프로토콜을 통해 통신하므로 Delegator는 Delegate가 누구인지 알 필요가 없음. ButtonDelegate 프로토콜만 채택하면 어떤 클래스든 delegate가 될 수 있어서 결합도가 낮아지고 교체가 쉬워짐.

UIKit에서 UITableViewDelegate, UITextFieldDelegate 등이 전부 이 패턴으로 동작함.

profile
정체되지 않는 성장

0개의 댓글