为何id调用respondsToSelector正常,id<协议>调用却报错?
为什么
id调用respondsToSelector:不报错,id<DummyProtocol>却报错? 这事儿其实和Objective-C编译器对id类型的特殊处理有关,我给你拆解清楚:
1. 为什么纯id的情况没问题?
虽然id本质是objc_object*的C结构体指针,但编译器对它有「特殊照顾」:默认会认为id类型的对象隐式遵循NSObject协议。
所以哪怕你写的是id objc = nil;,编译器也会认可respondsToSelector:这类NSObject协议里定义的方法,不会报错。而且运行时给nil发消息本来就是Objective-C的合法行为,自然能正常跑。
2. 为什么加了无NSObject继承的协议就报错?
当你把类型写成id<DummyProtocol>时,编译器的检查逻辑就变了:它只会承认这个协议本身定义的方法,以及该协议继承来的方法。
因为你的DummyProtocol没有继承NSObject,NSObject协议里的respondsToSelector:不在这个协议的方法集合里,编译器找不到对应的实例方法声明,自然就抛出错误了。
两个快速解决办法
- 让协议继承NSObject:
这样编译器就知道遵循该协议的对象也实现了NSObject的所有方法。@protocol DummyProtocol <NSObject> @end - 显式转换为
id再调用:
强制让编译器回到对[(id)objc respondsToSelector:@selector(foo)];id的默认处理逻辑,就能绕过检查。
内容的提问来源于stack exchange,提问作者NSFish
相关产品推荐
相关产品推荐

