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

swa*_*ner 48 core-data objective-c

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

我唯一的线索是,我有一个对象updatedObjects:在我的NSManagedObjectContext-但似乎有不妥的地方.

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

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

非常感谢你!

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

Dan*_*ert 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.
}
Run Code Online (Sandbox Code Playgroud)

  • 简短回答:是的. (3认同)
  • 有没有办法避免这个?调试时非常讨厌,因为我希望一直有一个异常断点.这样,它经常停止而不是一个"真正的"例外...... (2认同)

rus*_*hop 18

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

  1. 删除"所有Objective-C Exceptions"断点
  2. 添加符号断点 objc_exception_throw
  3. 在断点上设置条件为 (BOOL)(! (BOOL)[[(NSException *)$eax className] hasPrefix:@"_NSCoreData"])
  4. 我还想添加一个动作,调试器命令,"po $ eax",它通常会打印出异常细节

$ eax是模拟器的正确寄存器,$ r0适用于设备.您可以创建两个单独的断点并根据需要启用/禁用它们.

有关原始答案使用Xcode的All Exceptions断点时,请参阅忽略某些异常


Yon*_*nat 8

我遇到了类似的问题.最后,我发现了问题:

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

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

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