NSManagedObjectContext:异常断点在save:方法处停止,但没有日志/崩溃/错误

时间:2011-12-01 07:01:38

标签: objective-c core-data

我在一个多线程iOS应用程序中使用CoreData,一切似乎都运行正常 - 除非我在XCode中打开异常断点。每当我做一些CoreData工作时,断点就会在save:上的NSManagedObjectContext - 方法停止 - 但之后NSError为零。我在日志中也没有任何内容(除了:Catchpoint 2 (exception thrown).),应用程序没有崩溃......所以很难说出现了什么问题。

我唯一的线索是我updatedObjects:中的NSManagedObjectContext中有一个对象 - 但似乎没有任何问题。

我的问题与this question on stackoverflow 非常相似,但唯一的答案对我没有帮助;我很确定我已经把所有东西都包括在内了。

这里有什么问题?或者是否有其他可能获得一些错误信息?

非常感谢!

编辑:显示代码非常困难。我正在使用objectID加载对象,在分配给当前线程的上下文中编辑和存储它们。我已经检查过了 - 当前线程的上下文总是正确的;每个线程都有自己的上下文,这应该不是问题。如果只有某人可以告诉我如何从该错误/异常中获取更多信息 - 或者如果我不得不关心它,那将会很有帮助。在我看来好像异常是在'save'方法中捕获的,所以可能是一个“正常”的行为?

5 个答案:

答案 0 :(得分:73)

这是正常行为。 CoreData使用异常抛出&在内部处理某些程序流程。我和CoreData的人谈过这件事。这可能看起来很奇怪,但这是他们很久以前做出的设计决定。

当您遇到异常时,请确保在调用-[NSManagedObjectContext save:]和抛出异常之间的回溯中没有任何代码。致电-save:很可能会回复您的代码,例如如果你正在观察NSManagedObjectContextObjectsDidChangeNotification,如果你在处理这些通知时做了坏事,显然你有错。

如果您要退出-save:方法,并且返回值为YES,那么一切都很好。

请注意,您应该检查返回值,使用error != nil来检查错误。正确的检查是:

NSError *error = nil;
BOOL success = [moc save:&error];
if (!success) {
    // do error handling here.
}

答案 1 :(得分:17)

你可以避免这些无用的休息;正如其他人已经指出这是正常的CoreData行为(但非常讨厌!)

  1. 删除“所有Objective-C Exceptions”断点
  2. objc_exception_throw
  3. 上添加符号断点
  4. 将断点的条件设置为(BOOL)(! (BOOL)[[(NSException *)$eax className] hasPrefix:@"_NSCoreData"])
  5. 我还想添加一个动作,调试器命令,“po $ eax”,它通常打印出异常细节
  6. $ eax是模拟器的正确寄存器,$ r0适用于设备。您可以创建两个单独的断点并根据需要启用/禁用它们。

    有关原始答案,请参阅Ignore certain exceptions when using Xcode's All Exceptions breakpoint

答案 2 :(得分:8)

我有类似的问题。最后,我发现了问题:

我向 NSManagedObjectContextDidSaveNotification 添加了一个观察者,该观察者在没有从通知中心移除自身的情况下被释放。当其内存被分配给其他对象时,通知中心尝试调用该对象并引发异常,因为它无法找到正确的选择器。由于某种原因,此异常“不可见”,但导致CoreData引发其自身的异常。

一个位置很好的 removeObserver:调用修复了问题。

希望这可以帮助遇到这种情况的其他人。

答案 3 :(得分:0)

我的代码中出现了类似的问题。我终于发现问题是由于我的模型发生了变化,我使用的EncryptedCoreData NSPersistentStoreCoordinator没有设置为自动迁移,正如我过去期待MagicalRecord一样。

唯一的症状是这个断点,没有任何其他消息。通过删除并重新安装应用程序(暂时)解决了问题,并通过将模型版本和相应的密钥(NSMigratePersistentStoresAutomaticallyOption: true, NSInferMappingModelAutomaticallyOption: true)添加到我的堆栈设置中来永久解决。

答案 4 :(得分:0)

我遇到了同样的问题,我发现的是协调器会在出现合并问题时抛出异常。我已经删除了我的合并策略(默认是错误),然后在调用save时错误指针不再为nil。这也让我相信我的代码还可以。