Подтвердить что ты не робот

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

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

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

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

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

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

И с обычной типичной реализацией

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

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

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

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

...

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

warning: category 'SomeCategory' не полностью реализует протокол NSObject

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

4b9b3361

Ответ 1

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

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

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

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

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

Ответ 2

Любая возможность объявления протокола включает протокол NSObject? Вот так:

@protocol SomeDelegate <NSObject>
...

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

Ответ 3

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

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