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

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

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

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

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

Ответы [ 3 ]

13 голосов
/ 23 мая 2009

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

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

4 голосов
/ 23 мая 2009

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

Так что я думаю, что вы видите небольшую задержку с более ранних дней до ключевого слова @optional.

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

1 голос
/ 23 мая 2009

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

...