Что такое паттерн Делегат (Delegate) в iOS?

«Что такое паттерн Делегат (Delegate) в iOS?» — вопрос из категории Паттерны, который задают на 22% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Паттерн Делегат — это поведенческий паттерн проектирования, который позволяет одному объекту (делегату) обрабатывать события или предоставлять данные для другого объекта. Это основной способ реализации обратной связи и разделения ответственности в Cocoa Touch.

Основные компоненты:

  1. Протокол делегата: Определяет контракт — методы, которые может (или должен) реализовать делегат.
  2. Объект-источник (Delegating Object): Имеет слабую (weak) ссылку на делегата. Он вызывает методы делегата при наступлении событий (например, пользователь выбрал ячейку таблицы).
  3. Делегат: Объект, который подписывается на протокол и реализует его методы, чтобы реагировать на события.

Пример:

// 1. Протокол делегата
protocol CustomButtonDelegate: AnyObject {
    func buttonDidTap(_ button: CustomButton)
}

// 2. Объект-источник (имеет делегата)
class CustomButton: UIButton {
    weak var delegate: CustomButtonDelegate? // Слабая ссылка для избежания циклов удержания

    @objc private func handleTap() {
        delegate?.buttonDidTap(self) // Сообщение делегату о событии
    }
}

// 3. Делегат (реагирует на события)
class ViewController: UIViewController, CustomButtonDelegate {
    let button = CustomButton()

    override func viewDidLoad() {
        super.viewDidLoad()
        button.delegate = self // Установка делегата
    }

    // Реализация метода протокола
    func buttonDidTap(_ button: CustomButton) {
        print("Кнопка была нажата")
    }
}

Почему weak? Чтобы избежать цикла сильных ссылок (например, когда ViewController владеет button, а button держит сильную ссылку на ViewController).