примечание: для этой статьи требуются базовые знания программирования.

Начну с примера из реальной жизни. Как известно, для управления моторизованными транспортными средствами физическим лицам необходимо иметь водительские права. Это требование устанавливается правительством. Таким же образом мы можем создавать протоколы (с ключевым словом протокол) и определять наши требования для классов и структур в Swift. Вот синтаксис:

protocol YourProtocol {
   // requirements here
}

У класса или структуры может быть несколько протоколов. Если в протоколе требуется функция (или переменная), все структуры или классы, имеющие этот протокол, должны иметь эту функцию (или переменную ). Пора увидеть это на реальном примере и понять, когда следует использовать протоколы:

Предположим, у меня есть класс Автомобиль с диском и топливом методы (которые используются для управления автомобилем и заправки его определенным количеством бензина соответственно), автомобиль под названием «Ford» и заправочная станция (структура PetrolStation) для добавления топлива в автомобили:

На первый взгляд все в порядке, пока мы не хотим добавить электромобиль в качестве подкласса Автомобиль. Независимо от типа автомобиля, мы принимаем этот тип (электромобиль) как автомобиль (поскольку он фактически один). Но у этого автомобиля не будет метода доливки бензина (метод топлива), что в нашем случае является проблемой. Еще одна проблема возникает, когда на заправку приезжает мотоцикл. В этом случае наша АЗС откажется заправлять мотоцикл, сказав: «Извините, нам нужно заправлять только автомобили», что неверно. Именно здесь вступают в игру протоколы. Давайте добавим протокол (с именем FuelAddable), имеющий (требующий) метод топлива, и заправочные станции будут заправлять автомобили только с этим протоколом. :

Если я добавлю транспортное средство с протоколом FuelAddable, но не добавлю требуемый метод, при попытке сборки будет выдана показанная ошибка:

Теперь я хочу показать реальный пример из приложения для iOS. Я хочу добавить в приложение представление панели навигации и повторно использовать его во всех представлениях. Структура представления такая:

Левая (назад) кнопка в представлении необязательна. Поэтому обработчик нажатия (касания) для кнопки будет необязательным. Давайте посмотрим на код, который строит это представление (я не включил визуальную сторону, поскольку нет необходимости понимать протоколы):

Примечание. Вы можете пропустить методы setupLayout и awakeFromNib, поскольку они используются для добавления ограничений и добавления представления в качестве подпредставления родительского Посмотреть. К сведению: код, написанный в области действия didSet, будет действовать, когда переменная будет установлена. Выходы поступают со стороны просмотра.

Как вы видите в примере кода, я ничего не делал во время касания кнопки возврата. Причина в том, что родительское представление должно решать, что произойдет, когда пользователь вернется, и это представление не должно знать, что происходит при нажатии кнопки «Назад». Как вы это почувствуете (я надеюсь, что почувствуете), пришло время добавить протокол для родительского представления. Давайте сначала создадим протокол, который будет требовать от обработчика нажатия кнопки "Назад":

Примечание. Я использовал @objc, чтобы иметь возможность использовать необязательные свойства.

Теперь я подключусь к родительскому элементу, объявив необязательную (потому что нам нужно обрабатывать только нажатие кнопки возврата, а сама эта кнопка не является обязательной) переменную с именем делегат (подробнее о делегатах здесь) , и вызывая его методы:

Теперь, когда нажата кнопка "Назад", будет вызван метод делегата onBack.

Надеюсь, эта статья помогла вам окунуться в мир протоколов в Swift. Если у вас есть какие-либо вопросы или отзывы, не стесняйтесь обращаться ко мне (контакты доступны на mrgazanfarli.com).

Ссылка: Swift docs