8

Я искал способ использовать дополнительные методы протокола и иметь чистый код. Другими слова:
1: Нет respondsToSelector: звонков по всему моему коду
2. Должен работать для любого метода подписи, поэтому метод категории на NSObject делает чек и вызов performSelector: вне (и NSInvocation имеет проблемы с сотрудничающим АРК)
3: Это solution, ИМО, претендует на универсальность, но имеет все недостатки 1Что случилось с использованием категории в NSObject для обеспечения реализации протокола по умолчанию?

в конце концов я пришел с этой идеей:

@protocol MyProtocol <NSObject> 
@optional 
-(void)optionalMethod; 
@end 

@interface ClassA : NSObject <MyProtocol> 
@end 

@implementation ClassA 

-(void)optionalMethod{ 
    NSLog(@"ClassA implements optionalMethod"); 
} 

@end 

@interface ClassB : NSObject <MyProtocol> 
@end 

@implementation ClassB 
//classB does not implement optionalMethod 
@end 

@interface NSObject (DefaultMyProtocolImplementation) 
-(void)optionalMethod; 
@end 

@implementation NSObject (DefaultMyProtocolImplementation) 
-(void)optionalMethod{ 
    NSLog(@"%@ does not implement optionalMethod", NSStringFromClass([self class])); 
} 
@end 

Это, кажется, работает, то есть:

... 
ClassA *objA = [[ClassA alloc] init]; 
ClassB *objB = [[ClassB alloc] init]; 

[objA optionalMethod]; //prints "ClassA implements optionalMethod" 
[objB optionalMethod]; //prints "ClassB does not implement optionalMethod" 

Хотя во многих местах в Интернете обсуждается эта проблема, я не наткнулся на это решение, и это заставляет меня думать, что с ним что-то не так - какой-то важный случай, когда он потерпит неудачу или будет непредсказуем.

Должен ли я просто сделать это, или мои действия действительно действительны?

+2

Связано: [Создание категории для классов, реализующих определенный протокол] (http://stackoverflow.com/q/17739562), и [ответ Алекс Грея на определение категорий для протоколов в Objective-C] (http://stackoverflow.com/a/19138382/603977), что указывает на [libextobjc] (https://github.com/jspahrsummers/libextobjc). –

+0

Единственное, о чем я могу думать до сих пор, это то, что вы не получите предупреждение компилятора для '[objectWhichDoesNotDeclareConformanceToTheProtocol theOptionalProtocolMethod];' Это на самом деле то, как изначально были реализованы факультативные методы протокола: [Неофициальный протокол в ObjC] (http: // stackoverflow.com/q/2010058). Другое дело, что методы, которые _you_ добавляют к классам инфраструктуры, в идеале должны быть префиксом, чтобы избежать столкновений. –

ответ

7

Методы, добавленные к существующим системным классам, должны быть префиксом каким-либо образом. То есть exec_myMethod или exec_doSomethingToThis:. Итак, ваше решение нарушает это.

Кроме того, это также означает, что класс не может отказаться от того, что может повести поведение метода по умолчанию @optional (что в принципе ничего не значит, потому что ваша реализация по умолчанию действительно должна быть не-op).

Итак, нет, в общем, нет ничего ужасного в том, что для обеспечения реализации по умолчанию за нарушение правила следует добавить правило для добавления методов по категориям в существующие классы. Но это не сложно.

Другой недостаток заключается в том, что вы загрязняете пространство имен методов. Это будет недостатком во время разработки в том, что Xcode будет кодировать все методы, легко избежать, просто не подвергая объявлениям (которые не нужно раскрывать). Во время выполнения это означает, что respondsToSelector: не полезен для этих методов, но это своего рода дизайн.

Тем не менее ... он пахнет обонятельным центром старого старого таймера.

Смежные вопросы