符合协议的id类型的KVC

时间:2014-09-18 18:34:32

标签: objective-c kvc

我偶然发现了Xcode 6中的键值编码问题。似乎不可能在id符合协议的情况下使用键值编码。

当属性声明为id时,编译器同意

@property (nonatomic, strong) id foo;

[foo setValue:@"value" forKey:@"key"];

当我设置id以符合协议时,我得到编译器错误。 “没有已知的选择器实例方法......”。

@property (nonatomic, strong) id<MyProtocol> foo;

[foo setValue:@"value" forKey:@"key"];

如果我将类型设置为NSObject,它会起作用,如下所示:

@property (nonatomic, strong) NSObject<MyProtocol> *foo;

[foo setValue:@"value" forKey:@"key"];

协议“MyProtocol”符合NSObject,但据我所知,该对象必须是NSObject的子类才能使KVC正常工作。但为什么第一种情况有效而不是第二种?

1 个答案:

答案 0 :(得分:3)

这在Xcode 6中并不新鲜。(我刚刚测试了Xcode 5.1.1并收到错误。)规则如下:

  • 编译器允许您向裸id发送任何消息。

  • 如果消息是由其中一个命名协议定义的,编译器只允许您向id<Protocol1, Protocol2, Protocol3, ...>发送消息。

  • 如果消息由类中的某个命名协议定义,编译器将只允许您向SomeClass<Protocol1, Protocol2, Protocol3, ...>发送消息。该类定义的消息包括由其超类及其类别定义的消息。

setValue:forKey:方法在NSKeyValueCoding categoryNSObject class中定义。它未在NSObject protocol上定义。