2

我有一个类,它在某些时候通过 Core Data fetch 获取一堆数据,然后将在 XCode 中以通常的 Core Data 方式创建的对象插入NSManagedObjectNSMutableSet. 根据事情的进展情况,其中一些对象可能最终会出现在其他几个集合中。到现在为止还挺好。

但随后会发生以下情况:

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但 ,previousResults和任何其他引用了MyObject被触摸的任何 s 的对象createAnnoFromMyObject:最终都被丢弃了。

通过破坏我的意思是尝试访问它们会导致异常

-[MyObject beginningOfDocument]: unrecognized selector sent to instance...

当尝试使用该po命令在调试器窗格中查看任何这些集合时,也会发生同样的情况。

我们尝试MyObject在 Core Data 中重新生成,但没有成功。谷歌上很少提到这个beginningOfDocument选择器,我们不知道有什么问题。尽管我们有一个可能会消除此问题的解决方法,但很高兴知道发生了什么。

4

2 回答 2

3

我还遇到了这个特定的无法识别的选择器问题——在 iOS5.xbeginningOfDocument中我的(子类)实例上调用了这个问题。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;
}
于 2013-01-31T21:04:29.007 回答
0

看起来您的 MyObject 正在被释放。我猜你在这种情况下使用的是 ARC,并且你没有任何东西持有 MyObject 对象(检查对象所在的 NSSets 是否也以某种方式被持有)。这意味着它将在当前运行循环结束时释放,您将看到您遇到的错误。

你可以运行 Zombies in Instruments 来证明这个理论。

于 2012-04-27T07:58:11.443 回答