gpt4 book ai didi

ios - 在 NSObject 上使用类别来提供默认协议(protocol)实现有什么问题?

转载 作者:可可西里 更新时间:2023-11-01 03:10:15 24 4
gpt4 key购买 nike

我一直在寻找一种使用可选协议(protocol)方法并拥有干净代码的方法。换句话说:
1:我的代码中没有respondsToSelector:调用
2. 应该适用于任何方法签名,因此 NSObject 上的类别方法进行检查并调用 performSelector: 已经过时(NSInvocation 在与 ARC 合作时存在问题)
3:这个solution ,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"

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

我应该这样做吗,或者我的担忧是否合理?

最佳答案

添加到现有系统类的方法应该以某种方式加上前缀。 IE。 exec_myMethodexec_doSomethingToThis:。因此,您的解决方案违反了这一点。

除此之外,它还意味着一个类不能选择退出任何默认 @optional 方法的行为(这基本上什么都没有,因为您的默认实现实际上应该是无操作)。

所以,不,总的来说,除了违反通过类别向现有类添加方法的应该添加前缀规则之外,提供默认实现并没有什么可怕的错误。但这不是硬性规定。

另一个缺点是您正在污染方法命名空间。这将是开发过程中的一个缺点,因为 Xcode 将编码完成所有方法,只需不公开声明(不需要公开)即可轻松避免。在运行时,这意味着 respondsToSelector: 对这些方法没有用,但这是设计使然。

仍然......它闻到了这个老计时器的代码嗅觉中心。

关于ios - 在 NSObject 上使用类别来提供默认协议(protocol)实现有什么问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19329309/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com