NSObject协议附带了库存协议模板,但它似乎并不是实际协议实现所必需的。离开它似乎完全没有改变。那么,协议是否真的有必要从中继承,还是只是一个不必要的附加组件?
答案 0 :(得分:20)
多年来,我(和许多像我一样)并没有使我们的协议符合<NSObject>
。它工作正常。但它往往很烦人。最常见的烦恼是,您无法使用respondsToSelector:
而无法转回NSObject*
(哪种方式会破坏协议的全部内容)。因为没有@optional
因为没有@optional
,所以这并不重要。因此我们都没有担心它(因为没有{{1}我们在那些日子里根本没有使用协议他们并没有那么有用。然后ObjC2伴随着可选方法的精彩添加,突然respondsToSelector:
重要。我们花了一些时间来讨论这个问题,但最终我们开始发现,如果你的协议符合<NSObject>
,生活会更简单。幸运的是,这已经进入Xcode,让每个人都能更方便地做事。
但不,你不必这样做。在许多情况下,这并不重要。但是没有太多理由不去做,所以我推荐它。
答案 1 :(得分:7)
不一定。委托只是一个帮助对象 - 唯一的要求是委托类放在它上面的那些要求。如果要形式化给定委托的要求,请创建正式协议,即使用@protocol
指令声明协议。如果符合NSObject协议是其中一项要求,您可以使您的协议采用它:
@protocol MyDelegateProtocol <NSObject>
//...
@end
那就是说,我没有看到任何理由创建一个不是从NSObject或者NSProxy派生的委托,并且这两个类已经符合NSObject协议。
答案 2 :(得分:1)
并非每个对象都必须继承NSObject
所以我想如果您希望这样的对象符合您的协议,则不一定必须符合NSObject。
符合NSObject让编译器知道对象符合基础 - 检查出NSObject Protocol Reference。不用说我符合NSObject编译器如何知道我符合这一点?
NSObject
定义为
@interface NSObject <NSObject> {
Class isa;
}
而id
定义为
typedef struct objc_object {
Class isa;
} *id;
因此对于id
,编译器不知道它符合NSObject
答案 3 :(得分:1)
推荐而非强制性。
根据Apple的官方文件 ProgrammingWithObjectiveC.pdf
如果您尝试在ID上调用
respondsToSelector:
方法 符合上面定义的协议,你将得到一个编译器 错误,没有已知的实例方法。一旦你符合资格 带有协议的id,allstatic类型检查返回;你会得到 如果您尝试调用未在中定义的任何方法,则会出错 指定的协议。避免编译器错误的一种方法是设置 自定义协议采用NSObject协议。
上面定义的协议是一个不符合NSObject
协议的协议。
例如,最佳做法是定义要符合的协议 到NSObject协议(一些NSObject行为是从中分离出来的 它的类接口成为一个单独的协议; NSObject类 采用NSObject协议)。