我一直在看到一些类似于以下内容的代码:
@protocol MyProtocol <NSObject>
// write some methods.
@end
MyProtocol符合NSObject协议有什么特别的原因吗?如果您执行以下操作,那就不那么多了:
id <MyProtocol> foo; // foo here conforms to NSObject AND MyProtocol?
只是好奇逻辑是什么。
答案 0 :(得分:31)
声明类似
的变量时 id<MyProtocol> var;
Objective-C编译器只知道MyProtocol
中的方法,如果您尝试调用任何NSObject
方法,例如-retain/-release
,就会产生警告实例。因此,Cocoa定义了NSObject
协议,它反映了NSObject
类和实例方法。通过声明MyProtocol
实现NSObject
协议,您可以向编译器提示所有NSObject
方法将由实现MyProtocol
的实例实现。
为什么这一切都是必要的? Objective-C允许对象从任何根类下降。在Cocoa中,NSObject是最常见的,但不是唯一的根类。例如,NSProxy
也是一个根类。因此,id
类型的实例不会必然继承NSObject
的方法。
答案 1 :(得分:28)
我很确定你这样做的原因是将NSObject成员(比如retain和release)添加到你的协议中。从技术上讲,你仍然可以发送这些消息但是没有它就会收到编译器警告。
答案 2 :(得分:22)
当您拥有具有@optional
方法的协议时(例如“现代”Objective-C 2.0委托经常使用此技术),这也非常方便如果您不包含NSObject
协议,那么'当你试图在对象上调用respondsToSelector:
时会收到警告。
答案 3 :(得分:2)
我在代码中从未这样做,但我可以看到它的优点。如果您将参数作为id <SomeProtocol>
传递,则需要重新强制转换它,如果您想在该对象上调用任何NSObject的方法。
答案 4 :(得分:2)
如果你使用任何NSObject协议方法,例如retain,release,class,classname,编译器会给你警告,除非你的Protocol还包含NSObject协议。