在NSObject上使用类别提供默认协议实现有什么问题?
我一直在寻找一种方法来使用可选的协议方法,并有干净的代码。 换一种说法:
1:No respondsToSelector:
全部调用我的代码
2,应该为任何方法签名工作,所以NSObject做检查和调用performSelector:
的类别方法是out(和NSInvocation有问题与ARC合作)
3:这个解决scheme ,国际海事组织,假装是普遍的,但具有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"
虽然很多地方在网上讨论这个问题,但是我还没有偶然发现这个解决scheme,这让我觉得它有什么问题 – 一些主要的情况下,它会失败,或者是不可预测的。
我应该这样做,还是我的顾虑是有效的?
添加到现有系统类的方法应该以某种方式添加前缀。 即exec_myMethod
或exec_doSomethingToThis:
所以,你的解决scheme是违反了。
除此之外,这也意味着一个类不能select任何默认的@optional
方法的行为(这基本上没有什么,因为你的默认实现应该是一个没有操作)。
因此,总体而言,除了违反应用程序添加前缀规则(通过类别向现有类添加方法)之外提供默认实现,没有什么可怕的错误。 但这不是一个硬性规定。
另一个缺点是你正在污染方法命名空间。 这在开发过程中会是一个缺点,因为Xcode将会完成所有的方法,通过简单地不暴露声明(不需要暴露)就可以轻松避免。 在运行时,这意味着respondsToSelector:
对这些方法没有用处,但这是有点devise的。
仍然…它闻到这个老计时器的代码嗅觉中心。