在NSObject上使用类别提供默认协议实现有什么问题? [英] What's wrong with using a category on NSObject to provide a default protocol implementation?

查看:128
本文介绍了在NSObject上使用类别提供默认协议实现有什么问题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在寻找一种方法来使用可选的协议方法并拥有干净的代码。换句话说:

1:否 respondsToSelector:调用我的代码全部

2.应该适用于任何方法签名,所以在NSObject上进行检查并调用 performSelector:的类别方法已经用完(并且NSInvocation与ARC合作有问题)

3:这个解决方案,IMO,假装是普遍的但是有所有缺点1

I've been looking for a way to use optional protocol methods and have clean code. In other words:
1: No respondsToSelector: calls all over my code
2. Should work for any method signature, so a category method on NSObject making the check and calling performSelector: is out (and NSInvocation has problems cooperating with ARC)
3: This solution, IMO, pretends to be universal but has all the drawbacks of 1

我最终提出了这个想法:

I eventually came up with this idea:

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

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

While many places online discuss this problem, I haven't stumbled upon this solution, which makes me think there's something wrong with it -- some major case where it will fail, or be unpredictable.

我应该这样做,或者我的关注是否有效?

Should I just do it, or are my concerns valid?

推荐答案

添加到现有系统类的方法应该以某种方式加上前缀。即 exec_myMethod exec_doSomethingToThis:。所以,你的解决方案违反了这一点。

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.

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

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.

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

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.

这篇关于在NSObject上使用类别提供默认协议实现有什么问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆