我在一个多线程iOS应用程序中使用CoreData,一切似乎都运行正常 - 除非我在XCode中打开异常断点。每当我做一些CoreData工作时,断点就会在save:
上的NSManagedObjectContext
- 方法停止 - 但之后NSError为零。我在日志中也没有任何内容(除了:Catchpoint 2 (exception thrown).
),应用程序没有崩溃......所以很难说出现了什么问题。
我唯一的线索是我updatedObjects:
中的NSManagedObjectContext
中有一个对象 - 但似乎没有任何问题。
我的问题与this question on stackoverflow 非常相似,但唯一的答案对我没有帮助;我很确定我已经把所有东西都包括在内了。
这里有什么问题?或者是否有其他可能获得一些错误信息?
非常感谢!
编辑:显示代码非常困难。我正在使用objectID加载对象,在分配给当前线程的上下文中编辑和存储它们。我已经检查过了 - 当前线程的上下文总是正确的;每个线程都有自己的上下文,这应该不是问题。如果只有某人可以告诉我如何从该错误/异常中获取更多信息 - 或者如果我不得不关心它,那将会很有帮助。在我看来好像异常是在'save'方法中捕获的,所以可能是一个“正常”的行为?
答案 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行为(但非常讨厌!)
objc_exception_throw
(BOOL)(! (BOOL)[[(NSException *)$eax className] hasPrefix:@"_NSCoreData"])
$ 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。这也让我相信我的代码还可以。