exe*_*r21 8 protocols objective-c objective-c-runtime ios objective-c-category
我一直在寻找一种方法来使用可选的协议方法并拥有干净的代码.换句话说:
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
Run Code Online (Sandbox Code Playgroud)
它似乎工作,即:
...
ClassA *objA = [[ClassA alloc] init];
ClassB *objB = [[ClassB alloc] init];
[objA optionalMethod]; //prints "ClassA implements optionalMethod"
[objB optionalMethod]; //prints "ClassB does not implement optionalMethod"
Run Code Online (Sandbox Code Playgroud)
虽然网上很多地方都在讨论这个问题,但我并没有偶然发现这个解决方案,这让我觉得它有些问题 - 一些重大案例,它会失败,或者是不可预测的.
我应该这样做,还是我的担忧有效?
添加到现有系统类的方法应该以某种方式作为前缀.即exec_myMethod或exec_doSomethingToThis:.所以,你的解决方案违反了这一点.
除此之外,它还意味着一个类不能选择退出默认@optional方法的行为(基本上没什么,因为你的默认实现应该是无操作).
因此,总的来说,除了违反应用添加前缀规则以通过类别向现有类添加方法之外,提供默认实现并不存在可怕的错误.但这不是一个严格的规则.
另一个缺点是您正在污染方法命名空间.这在开发过程中将是一个缺点,因为Xcode将编写完成所有方法的代码,通过简单地不暴露声明(不需要公开)就可以轻松避免.在运行时,这意味着respondsToSelector:对这些方法没用,但这有点像设计.
仍然......它闻到了这个旧计时器的代码嗅觉中心.
| 归档时间: |
|
| 查看次数: |
1080 次 |
| 最近记录: |