Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/40.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 为什么要将NSObject的协议附加到协议实现中_Iphone_Objective C_Cocoa - Fatal编程技术网

Iphone 为什么要将NSObject的协议附加到协议实现中

Iphone 为什么要将NSObject的协议附加到协议实现中,iphone,objective-c,cocoa,Iphone,Objective C,Cocoa,我看到了一些类似于以下内容的代码: @protocol MyProtocol <NSObject> // write some methods. @end @protocol-MyProtocol //写一些方法。 @结束 MyProtocol符合NSObject协议有什么特殊原因吗?如果你做了一些事情,比如: id <MyProtocol> foo; // foo here conforms to NSObject AND MyProtocol? id foo;/

我看到了一些类似于以下内容的代码:

@protocol MyProtocol <NSObject>
// write some methods.
@end
@protocol-MyProtocol
//写一些方法。
@结束
MyProtocol符合NSObject协议有什么特殊原因吗?如果你做了一些事情,比如:

id <MyProtocol> foo; // foo here conforms to NSObject AND MyProtocol?
id foo;//这里的foo是否符合NSObject和MyProtocol?

我只是好奇逻辑是什么。

我的代码中从来没有这样做过,但我可以看到它的优点。如果您以
id
的形式传递参数,如果您想在该对象上调用任何NSObject的方法,则需要重新强制转换该参数。

我很确定您这样做的原因是将NSObject成员(比如retain和release)添加到您的协议中。从技术上讲,您仍然可以以任何方式发送这些消息,但是如果没有它,您将收到编译器警告。

如果您有具有
@可选
方法的协议(例如,“现代”Objective-C 2.0代理经常使用此技术),如果您不包括
NSObject
协议,那么它也非常方便,当您尝试调用对象上的
respondsToSelector:
时,将收到警告。

当您声明一个类似

 id<MyProtocol> var;
id变量;
Objective-C编译器只知道
MyProtocol
中的方法,因此,如果您试图在该实例上调用任何
NSObject
方法,例如
-retain/-release
,则会产生警告。因此,Cocoa定义了一个映射
NSObject
类和实例方法的
NSObject
协议。通过声明
MyProtocol
实现了
NSObject
协议,可以提示编译器所有
NSObject
方法都将由实现
MyProtocol
的实例实现


为什么这一切都是必要的?Objective-C允许对象从任何根类下降。在Cocoa中,NSObject是最常见的,但不是唯一的根类<例如,code>NSProxy
也是一个根类。因此,
id
类型的实例不一定继承
NSObject
的方法。

如果您使用任何NSObject协议方法,如retain、release、class、classname,编译器将向您发出警告,除非您的协议还包括NSObject协议。

为什么您不能只执行“NSObject*variable”? 然后您知道它是从NSObject派生的,但也符合协议,那么编译器就不会抱怨保留和释放。实际上,在使用任何@Protocol(NSObject)之前,这是可以的(就像强制转换到(NSObject*))方法。当然,除非实例实际上不是NSObject。更重要的是,将MyProtocol声明为实现NSObject协议澄清了协议的意图。如果您的协议不符合NSObject,我发现最好使用
id
。原因之一是使用
id
动态键入允许您若要调用任何方法,编译器可以找到其声明(无警告),而不仅仅是从NSObject继承或在协议中声明的方法。这可能既危险又非常有用,具体取决于您是否做出了安全的假设。:-“从技术上讲,您仍然可以以任何方式发送这些消息”如果您不知道对象是否实现了NSObject协议,则无法保证对象能够理解这些消息。这是一个足够可靠的回答。这比当今公认的答案更为相关,因为ARC消除了任何人对保留/发布的担忧。