11

我一直在寻找一种使用可选协议方法并拥有干净代码的方法。换句话说:
1:respondsToSelector:我的代码中没有调用
2. 应该适用于任何方法签名,因此 NSObject 上的类别方法进行检查和调用performSelector:(并且 NSInvocation 与 ARC 合作有问题)
3:这个解决方案,IMO,假装是通用的,但具有 1 的所有缺点

我最终想出了这个主意:

@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"

虽然网上很多地方都在讨论这个问题,但我并没有偶然发现这个解决方案,这让我觉得它有问题——一些主要情况下它会失败,或者是不可预测的。

我应该这样做,还是我的担忧有效?

4

1 回答 1

8

Methods added to existing system classes should be prefixed somehow. I.e. exec_myMethod or exec_doSomethingToThis:. So, your solution is in violation of that.

Beyond that, it also means that a class cannot opt out of whatever the default @optional method's behavior might be (which is basically nothing because your default implementation really should be a no-op).

So, no, overall, there isn't something horrendously wrong with providing a default implementation beyond the violation of the should add prefix rule for adding methods via category to existing classes. But that isn't a hard rule.

The other downside is that you are polluting the method namespace. This will be a disadvantage during development in that Xcode will code complete all the methods, easily avoided by simply not exposing the declarations (which don't need to be exposed). At runtime, it means that respondsToSelector: isn't useful for these methods, but that is kind of by design.

Still... it smells to this old timer's code olfactory center.

于 2013-10-15T03:54:56.360 回答