我有一个类,在某些时候获取一堆带有Core Data fetch的数据,然后将以通常的Core Data方式在XCode中创建并因此从NSManagedObject
派生的对象插入到{{ 1}}。根据事情的运作方式,其中一些对象最终可能会出现在其他几个集合中。到现在为止还挺好。
但接下来会发生以下情况:
NSMutableSet
所有NSMutableArray* anArray = [NSMutableArray alloc] init;
[currentResults minus:previousResults]; // both are NSMutableSets
for(MyObject* obj in currentResults)
{
[anArray addObject:[createAnnoFromMyObject:obj]]; // nastiness happens here
}
都会从createAnnoFromMyObj:
中提取数据并返回实现obj
的对象。
问题是虽然我得到了一系列可用的注释,MKAnnotation
,currentResults
以及引用{{1}所触及的任何previousResults
的任何其他对象最终遭到破坏。
通过删除我的意思是尝试访问它们会导致
的异常MyObject
尝试使用createAnnoFromMyObject:
命令在调试器窗格中查看任何这些集合时,也会发生同样的情况。
我们尝试在Core Data中重新生成-[MyObject beginningOfDocument]: unrecognized selector sent to instance...
,但没有运气。在Google上很少提及这个po
选择器,我们不知道什么是错误的。虽然我们有一个可能会解决这个问题的解决方法,但知道发生了什么事情真的很不错。
答案 0 :(得分:3)
我还遇到了这个特定的无法识别的选择器问题 - 在iOS5.x的my(子类)beginningOfDocument
实例上调用了NSManagedObject
。这个问题看起来在iOS6中得到修复。我也证实了NSZombies没有给我什么,尽管它看起来确实是正确的直觉。
在我们的托管对象的valueForKey
查找期间抛出了无法识别的选择器异常,因此值得查看堆栈跟踪,看看这是否也是您抛出异常的地方。
在我们的例子中,“破碎”键是fullText
,是我们其中一个属性的名称。更改名称消除了问题。我的猜测是该名称在底层sqlite查询中导致错误(我不认为全文是一个关键字,但可能是在sqlite中进行全文搜索?),并且可能在iOS6中更好地清理查询参数。
你可以通过这个小作弊找出什么键/属性名称被破坏:暂时将你的valueForKey:
方法覆盖到NSLog,然后只需调用超类版本并返回它。即使文档说不要覆盖它(我们只是暂时找到有问题的属性),这是可以的,因为我们只是重写然后调用超类实现。
// Don't forget to remove me after the bug is fixed!
- (id)valueForKey:(NSString *)key {
NSLog(@"Finding value for key: %@", key);
return [super valueForKey:key];
}
然后,当您再次运行时,您会在崩溃前看到对valueForKey:
的最后一次调用,并知道哪个属性名称已被破坏。
如果您仍然无法解决哪个是不成功的查找,那么您可以使用更详细的信息:
// Don't forget to remove me after the bug is fixed!
- (id)valueForKey:(NSString *)key {
NSLog(@"Finding value for key: %@", key);
id retVal = [super valueForKey:key];
NSLog(@"Success for key: %@", key); // or print retVal for fun
return retVal;
}
答案 1 :(得分:0)
看起来你的MyObject被释放了。我猜你在这种情况下使用ARC,并且你没有任何东西保持MyObject对象(检查对象所在的NSSets是否也以某种方式被保留)。这意味着它将在当前运行循环结束时释放,你会看到你得到的错误。
你可以运行Zombies in Instruments来证明这个理论。