Почему iPhone SDK использует категории, а не протоколы, для некоторых делегатов?

StackOverflow https://stackoverflow.com/questions/900335

Вопрос

Насколько я понимаю, протоколы подобны интерфейсам на других языках - они объявляют ожидаемые методы, - в то время как категории позволяют добавлять новые методы к существующим типам (возможно, даже к типам, которыми вы не владеете).)

Почему же тогда iPhone SDK иногда использует категории для объявления типов делегатов?Обычно я ожидал бы, что у всех делегатов будет типизированный идентификатор<MyDelegateProtocol> но есть много примеров, когда это не так.

Например, смотрите NSURLConnection.Его делегат вводится как "id", а "контракт" объявляется как категория в NSObject (NSURLConnectionDelegate).

Итак:какова мотивация для использования категорий в этих случаях?

Это было полезно?

Решение

Objective-C 2.0 представила директиву @optional protocol, позволяющую объявлять определенные методы протокола необязательными.До Obj-C 2.0 категории использовались для разрешения необязательных методов делегирования (в частности, категории в NSObject, которые вызываются неофициальные протоколы).

Я предполагаю, что большая часть использования категории вместо протокола в iPhone SDK является пережитком эквивалентных классов Mac.Например, NSURLConnection существует как в SDK для Mac, так и для iPhone, поэтому код, скорее всего, является общим.Поскольку Apple еще не перешла к изменению всех классов Mac для использования официальных протоколов, у нас остается некоторая несогласованность.

Другие советы

До версии Objective-C, которая была выпущена вместе с OS X 10.5 и iPhone SDK под названием "Objective-C 2.0", создавать дополнительные протоколы можно было только с помощью категорий.В Objective-C 2.0 в протоколах было добавлено новое ключевое слово @optional, чтобы отметить, какие методы были необязательными (остальные неявно обязательны).

Поэтому я думаю, что то, что вы видите, - это небольшое отставание от предыдущих дней, предшествовавших ключевому слову @optional.

Редактировать:Чтобы ответить на последующие действия, которые появились в исходном вопросе:Мотивация для использования категории в NSObject / id для неофициального протокола частично заключается в том, чтобы документировать и группировать, какие методы объект может вызывать в своем источнике данных (или делегировать или что-то еще), и в меньшей степени, чтобы избежать предупреждений компилятора о том, что вы вызываете методы, о которых компилятор не знает, будут присутствовать в объекте, который получает вызов.Представьте, что вы тот, кто реализует класс, который вызывает эти методы источника данных - вы, вероятно, захотите проверить, присутствует ли метод, используя [obj responsestoselector:@selector(my:datasource:метод:)] всякий раз, когда вы заинтересованы в вызове my:datasource:метода:метод для объекта obj.

Это наследие пришло из objective-c 1.0, в котором нет "дополнительного метода протокола".

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top