Что такое протокол (protocol) в Swift?

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

Ответ

Протокол (protocol) в Swift — это абстрактный тип, который определяет контракт (blueprint) методов, свойств и других требований, подходящих для конкретной задачи или функциональности. Тип (класс, структура, перечисление) может принять (conform) протокол, предоставив реализацию для всех его требований.

Пример базового протокола:

// Определение протокола
protocol Drawable {
    var area: Double { get } // Требуемое вычисляемое свойство (только для чтения)
    func draw() // Требуемый метод
}

// Структура, принимающая протокол
struct Circle: Drawable {
    let radius: Double

    var area: Double {
        return Double.pi * radius * radius
    }

    func draw() {
        print("Рисую круг с радиусом (radius)")
    }
}

// Использование через протокольный тип
let shape: Drawable = Circle(radius: 5.0)
print(shape.area) // 78.53981633974483
shape.draw() // "Рисую круг с радиусом 5.0"

Основные возможности и применение:

  • Наследование протоколов: Протокол может наследовать один или несколько других протоколов.
    protocol ColoredDrawable: Drawable {
        var color: String { get set }
    }
  • Расширения протоколов (Protocol Extensions): Позволяют добавлять реализацию по умолчанию для методов и свойств, а также добавлять новые функциональности ко всем типам, принимающим протокол.
    extension Drawable {
        func drawWithBorder() {
            print("--- Начинаю рисование ---")
            draw()
            print("--- Заканчиваю рисование ---")
        }
    }
    shape.drawWithBorder() // Использует реализацию по умолчанию
  • Требования: Протоколы могут требовать:
    • Методы экземпляра и типа (static func)
    • Вычисляемые и хранимые свойства (с указанием get и/или set)
    • Инициализаторы (init)
    • Субскрипты (subscript)
  • Использование в архитектуре:
    • Делегирование (Delegation): Классический паттерн для обратной связи между объектами.
    • Полиморфизм: Работа с разнородными объектами через общий интерфейс.
    • Ограничения в обобщенном программировании (Generics): func process<T: Drawable>(_ item: T).
    • Протокол-ориентированное программирование (POP): Альтернатива наследованию классов, поощряющая композицию и использование value-типов (структур).