分配给自定义协议引用的任何对象始终由NSObject协议直接或由超类确认。那我为什么要这样做呢?
答案 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:
消息。