为什么 ObjC 的 protocol 都要遵从 NSObject 协议?

2013年11月20日 · 10 years ago

今天在改代码的时候看到定义的 delegate 里面都写了 <NSObject> 在后面:

@protocol APerfectDelegate <NSObject>

@optional
- (void)optionalSel;

@required
- (void)requriedSel;

@end

由于太久没写 ObjC 了,顺手就给去掉了。回头人告诉我这东西编译时会报 warning。我就觉得奇怪了,其实基本上常用的类都是以 NSObject 为基类的,除非是为了周密考虑,把以 NSProxy 为基类的类给排除掉,否则干嘛非得加个 <NSObject> 协议不可。问了人然后自己也试了一下,发现是在这里 warning:

// Instance method 'respondsToSelector:' not found
if ( _delegate != nil && [_delegate respondsToSelector:@selector(optionalSel)] ) {
            [_delegate optionalSel];
}

respondsToSelector 这个方法找不到。明白了,遵循 <NSObject> 是为了确保实现了这个方法,这样在调用的时候就可以直接用这个方法检测是否能响应这个 SEL 了。

其实在 ObjC 1.0 的时候,protocol 的这个 @optional 选项是不存在的,所有的 protocol 方法都是必须实现的。所以不遵循 <NSObject> 也没关系,只要判断指针是否存在然后直接调用就完了。但是 ObjC 2.0 加入了 @optional 特性,于是乎必须使用 的 respondsToSelector: 方法先做一次判断了。

references: Must Delegates Conform To The NSObject Protocol?