Какой смысл протоколов? - PullRequest
3 голосов
/ 04 мая 2011

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

@interface myClass <myProtocol>

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

Ответы [ 3 ]

4 голосов
/ 04 мая 2011

Протокол объявляет набор сообщений, на которые объект должен ответить (или с помощью @optional, может ответить). В Objective-C его единственная точка (почти) * - позволить компилятору отмечать предупреждения, если вы передаете объект, который не реализует все методы протокола с правильными сигнатурами.

Рассмотрим простой пример: NSMutalbeDictionary имеет метод -setObject: ForKey: , который устанавливает значение для конкретного ключа. Ключ объявлен как тип id, что означает, что вы можете передать любой объект, и компилятор не будет жаловаться. Тем не менее, документация для метода гласит:

Ключ копируется (используя copyWithZone:; ключи должны соответствовать протоколу NSCopying).

поэтому, если вы передадите объект, у которого нет метода -copyWithZone:, вы получите исключение во время выполнения, сообщающее, что ключ не отвечает на -copyWithZone:. Было бы неплохо, если бы компилятор обнаружил вашу ошибку.

Если бы Apple объявила метод

-(void)setObject:(id)anObject forKey:(id<NSCopying>)aKey;

компилятор знал бы о требовании для -copyWithZone: (это единственный метод, объявленный в NSCopying ) и обнаружил бы любые случаи прохождения несовместимых объектов во время компиляции. Я думаю, что причина, по которой они этого не сделали, заключается в обратной совместимости. Если bbum читает, он может знать настоящую причину, почему бы и нет.


* Я говорю «почти», потому что вы можете проверить, соответствует ли объект протоколу во время выполнения.

1 голос
/ 04 мая 2011

Кроме того, Xcode Code Sense может быть очень полезным, если вы используете протоколы. Иногда он предлагает пропущенные методы.

1 голос
/ 04 мая 2011

Objective-C может выполнять как статическую, так и динамическую типизацию, поэтому протоколы на самом деле не требуются для обычных случаев использования.Вы всегда можете набрать свой делегат как id и затем отправить ему любые сообщения, которые вы хотите.(Компилятор предупредит вас, если вы попытаетесь отправить сообщение, которое не видно из текущего файла. Это единственная проверка работоспособности, которую он может выполнить для id -типированных объектов без расширенного вывода типа.)

Но сужение типа id с помощью протоколов хорошо и рекомендуется, потому что 1) код более читабелен, 2) компилятор предупредит вас, если вы попытаетесь отправить делегату поддельное сообщение, и 3) вы получите лучший кодзавершение.

...