可变数组值关键字mutableArrayValueForKey在移除对象时导致NSMutableArray崩溃。

3
我遇到了以下代码崩溃的问题。self.items是一个NSManagedObjectsNSArray,其中包含一个类型为字符串的"id"属性:
NSMutableArray *allIDs = [self.items mutableArrayValueForKey:@"id"];
NSArray *presentIDs = // a subset of allIDs
[allIDs removeObjectsInArray:presentIDs];

这是崩溃信息:

'Unacceptable type of value for attribute: property = "id"; desired type = NSString; given type = __NSArrayM; value = ....

在调试器中输出后发现,对于普通的NSMutableArray,allID是一个NSKeyValueSlowMutableArray而不是__NSArrayM

所以我改成了这个,它可以工作:

NSMutableArray *allIDs = [[self.items valueForKey:@"id"] mutableCopy];

这两个调用之间有什么区别会导致前者崩溃而后者工作?我怀疑这与KVO和代理集合有关,但不太理解。
1个回答

2
我怀疑这与KVO和代理集合有关,但我不太理解。
是的,虽然不是KVO,而是KVC(键值编码)。
从NSKeyValueCoding协议参考中:
mutableArrayValueForKey: 返回一个可变数组代理,该代理提供对由给定键指定的有序ToMany关系的读写访问。
换句话说,mutableArrayValueForKey的目的是为了提供对接收器属性中存储的不可变数组的可变访问。
另一方面,KVC为类型为NSArray的属性提供了特殊的valueForKey:实现,导致目标数组将valueForKey:消息传播到其每个元素,并返回所有结果值的数组。
因此,在您的第二个示例中,将valueForKey:发送到items数组会导致通过向数组中的每个项目发送valueForKey:“id”来获得的值数组。如果items数组本身具有类型为NSArray *的名为id的属性,则第一个示例仅适用。

搞清楚了。我的困惑在于认为 mutableArrayValueForKey: 和可变版本的 valueForKey: 是相同的。 - James Kuang
是的,我认为第一次使用时它本质上是令人困惑的。 - jlehr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接