Может ли категория одновременно реализовывать протокол?

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

Вопрос

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

Пример делегирования (для наглядности, спасибо Ole!):

@protocol SomeDelegate <NSObject>
  - (void)someDelegateMessage;
@end

Пример категории:

@interface NSObject (SomeCategory) <SomeDelegate>
  - (void)someDelegateMessage;    
@end

И с типичной в остальном реализацией

@implement NSObject (SomeCategory)
  - (void)someDelegateMessage {}
@end

Когда я на самом деле пробую это, я получаю предупреждение для каждого метода NSObject:

предупреждение:неполная реализация категории 'SomeCategory'

предупреждение:определение метода для '-description' не найдено

...

предупреждение:определение метода для '-isEqual:' не найдено

предупреждение:категория 'SomeCategory' не полностью реализует протокол 'NSObject'

Работает нормально, если я удалю <SomeDelegate> из объявления, но, конечно, NSObject не распознается как SomeDelegate

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

Решение

Обходной путь заключается в объявлении протокола в категории, не имеющей реализации, и реализации метода в другой категории, например:

@interface NSObject (SomeCategory) <SomeDelegate>
  - (void)someDelegateMessage;    
@end

@implementation NSObject (SomeCategory_Impl)
  - (void)someDelegateMessage {}
@end

Если ты сделаешь это, NSObject будет считаться соответствующим <SomeDelegate> во время компиляции и выполнения проверяет наличие someDelegateMessage добьется успеха.Однако, conformsToProtocol: проверки во время выполнения завершатся неудачей.

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

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

Есть ли вероятность, что ваша декларация протокола включает в себя NSObject протокол?Вот так:

@protocol SomeDelegate <NSObject>
...

Вот откуда приходят предупреждения, потому что теперь ваша категория не реализует полный протокол.В тестовом коде, который я только что ввел, удалив NSObject из протокола удаляются предупреждения компилятора.

Если вы хотите, чтобы компилятор заткнулся по поводу отправки <NSObject> сообщения (и важно, чтобы вы помнили, что это имя протокола, а не имя класса), затем просто используйте переменные 'id', а не 'id', поскольку вы явно сообщаете компилятору "Это объект, который реализует только протокол SomeDelegate".

В качестве альтернативы вместо этого используйте NSObject в качестве типа переменной.

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