내일배움캠프 20일차

임클·2025년 3월 28일

내일배움캠프

목록 보기
21/44
post-thumbnail

일정


Delegate 패턴이란?

Delegate 패턴은 iOS에서 객체 간의 1:1 통신을 구현하기 위한 디자인 패턴입니다. 한 객체가 자신이 처리해야 할 작업이나 이벤트를 다른 객체에게 위임(delegate)하여 처리하도록 하는 방식으로 동작합니다. 주로 이벤트 처리콜백(callback)을 구현할 때 사용되며, 대표적인 예로는 UITableView에서 셀 선택 이벤트를 처리하는 경우가 있습니다.

  • 핵심 아이디어: 객체 A가 특정 작업을 직접 처리하지 않고, 객체 B에게 "이 일을 대신 처리해줘"라고 요청하는 구조입니다.
  • 특징: 객체 간의 의존성을 줄이고, 책임을 명확히 분리합니다.

Delegate 패턴은 어떤 상황에서 사용되나요?

Delegate 패턴은 아래와 같은 상황에서 유용하게 활용됩니다:

  1. 객체 간 느슨한 결합(Loose Coupling)이 필요할 때
    • Delegate를 사용하면 객체가 서로 직접 의존하지 않고, 중간에 프로토콜을 통해 통신하므로 결합도가 낮아집니다.
  2. 특정 이벤트에 대한 응답이 필요할 때
    • 예: 버튼 클릭, 스크롤 이벤트, 텍스트 입력 완료 등 사용자의 상호작용에 반응해야 할 때.
  3. 재사용 가능한 컴포넌트를 만들 때
    • 컴포넌트(예: 커스텀 버튼)의 동작을 외부 객체가 정의하도록 위임하여, 다양한 상황에서 유연하게 사용할 수 있습니다.

Delegate 패턴과 Notification, KVO의 차이점

Delegate 패턴 외에도 iOS에서는 NotificationKVO(Key-Value Observing)라는 통신 방식이 있습니다. 이들의 차이점을 아래 표로 정리했습니다.

특성Delegate 패턴NotificationKVO
통신 방식1:1 (한 객체가 한 객체에 위임)1:多 (한 객체가 여러 객체에 알림)프로퍼티 변화 감지
결합도프로토콜로 정의, 중간 정도매우 느슨함 (발신자-수신자 독립)객체 간 강한 의존 가능성
타입 안정성강함 (Protocol로 명확히 정의)약함 (문자열 기반)약함 (프로퍼티 이름 기반)
실행 시점동기적 (즉시 호출)비동기적 가능프로퍼티 변경 시 자동 알림
사용 예시UITableViewDelegate앱 전역 이벤트 (예: 화면 회전)데이터 모델 값 변경 감지

1. Delegate 패턴

  • 특징: 한 객체가 다른 객체에게 작업을 위임하며, 통신이 명확하고 타입 안전합니다.
  • 장점: 코드 가독성이 높고, 디버깅이 쉬움.

2. Notification

  • 특징: NotificationCenter를 통해 이벤트를 브로드캐스트하며, 여러 객체가 이를 수신할 수 있습니다.
  • 장점: 발신자와 수신자가 서로 알 필요 없어 유연함.
  • 단점: 문자열 기반으로 타입 안정성이 낮음.

3. KVO (Key-Value Observing)

  • 특징: 객체의 특정 프로퍼티 값 변화를 감지하고 알림을 받습니다.
  • 장점: 프로퍼티 변화에 자동 반응 가능.
  • 단점: 설정이 복잡하고, 메모리 누수 위험이 있음.

프로토콜을 활용한 Delegate 패턴 구현 방법

Delegate 패턴은 주로 Protocol을 사용해 구현됩니다. 아래는 구현 과정과 예제 코드입니다.

구현 단계

  1. Protocol 정의: Delegate가 수행해야 할 메서드를 정의합니다.
  2. Delegate 프로퍼티 추가: 작업을 위임할 객체에 delegate 프로퍼티를 선언합니다 (보통 weak으로 메모리 순환 참조 방지).
  3. Delegate 메서드 호출: 이벤트 발생 시 delegate의 메서드를 호출합니다.
  4. Protocol 채택: Delegate 역할을 할 객체가 프로토콜을 채택하고 메서드를 구현합니다.

예시 코드

1. Protocol 정의

protocol ButtonDelegate: AnyObject {
    func buttonDidTap(_ button: CustomButton)
}
  • AnyObject를 추가해 클래스만 프로토콜을 채택하도록 제한합니다.

2. Delegate를 사용하는 클래스

class CustomButton {
    weak var delegate: ButtonDelegate?
    
    func tap() {
        *// 버튼이 눌렸을 때 delegate에게 알림*
        delegate?.buttonDidTap(self)
    }
}
  • weak 키워드로 순환 참조를 방지합니다.
  • ?로 옵셔널 체이닝을 사용해 delegate가 nil일 경우 안전하게 처리합니다.

3. Delegate를 채택하는 클래스

class ViewController: UIViewController, ButtonDelegate {
    let button = CustomButton()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        button.delegate = self *// 자신을 delegate로 설정*
    }
    
    func buttonDidTap(_ button: CustomButton) {
        print("Button tapped!")
    }
}
  • ViewController가 ButtonDelegate를 채택하고, 버튼 탭 이벤트를 처리합니다.

동작 흐름

  1. CustomButton의 tap() 메서드가 호출되면,
  2. delegate?.buttonDidTap(self)를 통해 ViewController의 buttonDidTap 메서드가 실행됩니다.
  3. 콘솔에 "Button tapped!"가 출력됩니다.

0개의 댓글