Протокол, объявленный с помощью синтаксиса (@protocol
в Objective-C), используется для объявления набора методов, которые класс «принимает» (объявляет, что будет использовать этот протокол). Это означает, что вы можете указать в своем коде, что «вам все равно, какой класс используется, если он реализует определенный протокол». Это можно сделать в Objective-C следующим образом:
id<MyProtocol> instanceOfClassThatImplementsMyProtocol;
Если вы заявите это в своем коде, тогда любой класс, который «соответствует» протоколу MyProtocol , может использоваться в переменной instanceOfClassThatImplementsMyProtocol . Это означает, что код, использующий эту переменную, знает, что он может использовать любые методы, определенные в MyProtocol с этой конкретной переменной, независимо от того, какой это класс. Это отличный способ избежать шаблона проектирования наследования и избежать жесткой связи.
Делегаты используют языковую функцию протоколов. Шаблон проектирования делегирования - это способ разработки вашего кода для использования протоколов там, где это необходимо. В структурах Какао шаблон проектирования делегата используется для указания экземпляра класса, который соответствует конкретному протоколу. Этот конкретный протокол определяет методы, которые класс делегата должен реализовывать для выполнения определенных действий при данных событиях. Класс, который использует делегата, знает, что его делегат соответствует протоколу, поэтому он знает, что он может вызывать реализованные методы в определенные моменты времени. Этот шаблон проектирования является отличным способом разъединения классов, потому что он действительно облегчает обмен одного экземпляра делегата на другой - все, что должен сделать программист, это убедиться, что заменяющий экземпляр или класс соответствует необходимому протоколу (т.е. он реализует методы, указанные в протоколе)!
Протоколы и делегаты не ограничиваются только разработкой Objective-C и Mac / iOS, но язык Objective-C и фреймворки Apple интенсивно используют эту замечательную языковую функцию и шаблон проектирования.
Edit:
Вот пример. В структуре UIKit Cocoa Touch существует протокол UITextFieldDelegate . Этот протокол определяет серию методов, которые должны реализовывать классы, являющиеся делегатами экземпляра UITextField . Другими словами, если вы хотите назначить делегата для UITextField (используя свойство delegate
), вам лучше убедиться, что этот класс соответствует UITextFieldDelegate . Фактически, поскольку свойство делегата UITextField определяется как:
@property(nonatomic, weak) id<UITextFieldDelegate> delegate
Тогда компилятор выдаст предупреждения, если вы назначите ему класс, который не реализует протокол. Это действительно полезно. Вы должны заявить, что класс реализует протокол, и, говоря, что он это делает, вы даете знать другим классам, что они могут определенным образом взаимодействовать с вашим классом. Таким образом, если вы присваиваете экземпляр MyTextFieldDelegateClass свойству delegate
UITextField , UITextField знает , что он может вызвать некоторые конкретные методы (связанные с вводом текста, выделением и т. д.) вашего MyTextFieldDelegateClass . Он знает это, потому что MyTextFieldDelegateClass заявил, что будет реализовывать протокол UITextFieldDelegate .
В конечном итоге все это приводит к гораздо большей гибкости и адаптируемости кода вашего проекта, что, я уверен, вы скоро поймете после использования этой технологии! :)