You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何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:
    @protocol DummyProtocol <NSObject> @end
    
    这样编译器就知道遵循该协议的对象也实现了NSObject的所有方法。
  • 显式转换为id再调用:
    [(id)objc respondsToSelector:@selector(foo)];
    
    强制让编译器回到对id的默认处理逻辑,就能绕过检查。

内容的提问来源于stack exchange,提问作者NSFish

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:07:26