【发布时间】:2014-09-18 18:34:32
【问题描述】:
我偶然发现了 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 工作。但为什么第一种情况有效,而第二种情况无效?
【问题讨论】:
-
这与KVC没有任何关系;
id s = @"WATERMELONS"; [s lowercaseString]; id <MyProtocol> r = s; [r lowercaseString];的结果相同。 -
好吧,猜猜是有道理的。所以你不再被允许向符合协议的 id 发送任何消息?
-
id是免费的;编译器只知道这个东西是一个 ObjC 对象。当你指定一个协议时,你已经稍微限制了类型——你基本上是在说“我不在乎这到底是什么,只要它有来自MyProtocol的方法”——但看起来编译器需要尽可能地限制。 只有 来自该协议的方法才能编译。不过,我不知道为什么;类型论中可能有原因。 -
但这是 Xcode 6 中的新功能?
标签: objective-c kvc