我为什么要将自定义协议符合NSObject?

时间:2015-07-03 13:33:57

标签: ios objective-c iphone protocols nsobject

分配给自定义协议引用的任何对象始终由NSObject协议直接或由超类确认。那我为什么要这样做呢?

4 个答案:

答案 0 :(得分:1)

听起来您可能会尝试询问有关使用NSObject协议的问题,因为每个类都有NSObject作为祖先。

然后,答案是为真,每个对象都来自NSObject。大多数是,但NSProxy是一个不是的例子。 NSObject 协议中的方法是NSObject 的任何实例都应该实现的,因此通过实现NSObject protocol NSProxy能够提供与NSObject(类)派生的任何类相同的行为。

例如,您可以将-isEqual-hash等方法用于NSProxy的实例。

如果您正在创建NSObject类的子类,则无需声明您的类实现NSObject协议,因为NSObject类已经为您执行了此操作。< / p>

此外,正如您可以声明一个类采用以下协议:

@interface MyClass <SomeProtocol>

您还可以声明协议采用其他协议:

@interface MyProtocol <SomeProtocol>

因为,如上所述,每个类都不是NSObject(类)的子类,MyProtocol采用NSObject(协议)保证您可以调用NSObject方法。如果要指定方法采用采用YourProtocol的任何类型的对象,可以通过将类型指定为id<YourProtocol>来实现。但是,如果未声明YourProtocol采用NSObject协议,则您无法确定调用NSObject-isEqual方法是否安全,您可以'甚至使用-respondsToSelector:-isKindOfClass:检查它是否安全,因为这些方法本身是NSObject协议的一部分。

答案 1 :(得分:1)

我真的不知道,我是否帮助你。

如果你的意思是自定义协议总是向NSObject协议确认,那么就有一个非常简单的理由。这有点奇怪:

如果您键入对id的引用,编译器会接受他在编译翻译单元时看到的每条消息(“class”,“module”,您编译的文件)。

如果键入对id<protocol>的对象引用,则编译器仅接受在协议内声明的消息。但这永远不够!

@protocol MyProtocol
@optional
- (void)doItOrNot;
@end

您可以发送的唯一消息是-doItOrNot。因此编译此类代码将失败:

id<MyProtocol> ref = …;
if ([ref respondsToSelector:@selector(doItOrNot)]) // <- Error -respondsToSelector is not declared in the protocol.
…

通过在协议中添加NSObject协议,您可以导入一些基本声明。 (包括MM for MRC。)

答案 2 :(得分:0)

Cocoa定义了一个镜像NSObject类和实例方法的NSObject协议。通过声明您的自定义协议实现NSObject协议,您可以向编译器提示所有NSObject方法将由实现自定义协议的实例实现。

如果您不包含NSObject协议,当您尝试在对象上调用任何NSObject方法(例如respondsToSelector:)时,您将收到警告。

答案 3 :(得分:0)

。但问题是NSObject的许多核心功能 - 实际上,NSObject作为基类运行所需的所有核心功能 - 都是在NSObject协议中声明的。 (这种奇怪的架构使得NSObject和NSProxy都可以成为基类:它们都采用NSObject协议。)

现在,如果将对象的类型声明为id<MyDelegate>,则可以发送该对象的唯一消息是MyDelegate消息。那很好,通常;但是,如果你想发送它,比如说respondsToSelector:消息怎么办?该方法在NSObject协议中声明,而不是在MyDelegate协议中声明。所以编译器会阻止你。

有两种解决方案。要么将对象的类型声明为NSObject<MyDelegate>,要么使MyDelegate采用NSObject协议。无论哪种方式,编译器现在都满意,您可以发送此对象respondsToSelector:消息。