Я понимаю, какой цели служат протоколы (чтобы тип соответствовал установленному списку методов и / или свойств), но я не понимаю, какова цель протокола со всеми необязательными методами. Одним из примеров может быть UITextFieldDelegate.

Если все методы в протоколе являются необязательными, почему вы должны соответствовать протоколу, а не просто писать методы с нуля в своем классе? Я не понимаю, какова польза или цель соблюдения протокола в этом случае.

Являются ли дополнительные методы здесь просто предложениями функциональности, которые можно было бы реализовать?

3
Chris 1 Мар 2016 в 02:19

3 ответа

Лучший ответ

Исторически для делегатов и источников данных в Какао использовались неформальные протоколы. Неформальный протокол был реализован через категорию для класса NSObject:

@interface NSObject (NSTableViewDelegate)

- (int)numberOfRowsInTableView:(NSTableView *)tableView;

// ...

@end

Позже были введены дополнительные методы в протоколах. Это изменение приводит к лучшему документированию обязанностей класса. Если вы видите в коде, что этот класс соответствует NSTableViewDelegate, вы подозреваете, что где-то существует табличное представление, управляемое экземпляром этого класса.

Кроме того, это изменение приводит к более строгим проверкам во время компиляции. Если программист случайно назначит неправильный объект свойствам delegate или dataSource, компилятор выдаст предупреждение.

Но ваше предположение тоже верно. Дополнительные методы также являются предложениями по возможной функциональности.

1
Borys Verebskyi 29 Фев 2016 в 23:51

Протокол устанавливает контракт для интерфейса между одним объектом и другим. Тот факт, что методы являются необязательными, просто говорит о том, что вам не нужно реализовывать этот конкретный метод, но вы можете, если ваше приложение требует этого.

Как правило, если вы соответствуете протоколу, для которого все методы являются необязательными, вы делаете это по какой-то причине, а именно, что вы планируете реализовать один или несколько из этих методов. Тот факт, что все методы протокола являются необязательными, не означает, что вы не будете реализовывать ни один из них, а просто то, что вы можете выбрать те, которые подходят для вашей конкретной ситуации.

Например, рассмотрим протокол UITextFieldDelegate. Обычно вы соглашаетесь с этим, потому что вы хотите указать, например, следует ли разрешить вставку определенных символов в текстовое поле или что делать при нажатии клавиши возврата. Иногда вы хотите реализовать только первое. Иногда вы хотите реализовать только последнее. Иногда вы делаете и то, и другое. Но только потому, что вы решили реализовать одно или другое, не означает, что вы обязательно хотите реализовать другой (но вы можете, если хотите). Честно говоря, если вы действительно не хотели реализовывать какой-либо из методов, вы, вероятно, даже не удосужились бы указывать delegate текстового поля и не удосужились указать, что вы соответствуете протоколу. .

В итоге протокол, который состоит исключительно из необязательных методов, в основном говорит: «Если вам это нужно, это документированный интерфейс для методов, которые вы можете выбрать для реализации». Протокол по-прежнему очень полезен для установления возможных интерфейсов, но не заставляет вас реализовывать те методы, которые вам не нужны.

1
Rob 1 Мар 2016 в 00:08

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

Если все методы в протоколе являются необязательными, зачем вам соответствовать протоколу, а не просто писать функции с нуля в своем классе?

Соответствие протоколу позволяет вашему классу сообщать другому объекту о методах, которые у него есть, при этом другому объекту не нужно знать о вашем классе. Это действительно полезно при использовании Delegation. поскольку это позволяет делегату решить, какую информацию он хочет получить / предоставить другому классу.


Например, протокол UIScrollViewDelegate определяет только необязательные методы. Допустим, у нас есть класс Foo, который мы хотим знать, когда что-то меняется с помощью UIScrollView.

Если бы мы решили выбросить этот протокол и реализовать функции с нуля, как бы мы сказали UIScrollView, какие методы мы реализуем и какие методы вызывать при наступлении определенного события? Нет никакого хорошего способа это узнать. Когда UIScrollView был собран, он не знал о Foo, поэтому не мог знать, какие методы он реализует. Кроме того, Foo не имеет возможности узнать, какие методы могут быть вызваны для него UIScrollView.

Однако когда был построен UIScrollView, он знал о UIScrollViewDelegate. Итак, если Foo соответствует протоколу UIScrollViewDelegate, теперь существует общее определение, которому могут следовать как Foo, так и UIScrollView. Таким образом, Foo может реализовать любые методы, которые ему нужны, например scrollViewDidScroll:, а UIScrollView просто нужно проверить, реализовал ли делегат методы в UIScrollViewDelegate.

1
Craig Siemens 29 Фев 2016 в 23:47