NSManagedObjectContext: exception breakpoint stops at save: method, but no log/crash/error
Solution 1:
This is normal behavior. CoreData uses exception throwing & handling internally for some of its program flow. I talked to the CoreData people about this. It may seem odd, but that's a design decision they made a long time ago.
When you hit the exception, make sure there's none of your code in the backtrace between your call to -[NSManagedObjectContext save:]
and the exception being thrown. Calling -save:
is very likely to call back into your code, e.g. if you're observing NSManagedObjectContextObjectsDidChangeNotification
, and if you're doing bad things when you're handling those notification, obviously you're at fault.
If you're exiting the -save:
method, and the return value is YES
, everything is good.
Please note, that you should check the return value, do not use error != nil
to check for an error. The correct check is:
NSError *error = nil;
BOOL success = [moc save:&error];
if (!success) {
// do error handling here.
}
Solution 2:
You can avoid these useless breaks; as others have pointed out this is normal CoreData behavior (but highly annoying!)
- Remove the "All Objective-C Exceptions" breakpoint
- Add a Symbolic Breakpoint on
objc_exception_throw
- Set a Condition on the Breakpoint to
(BOOL)(! (BOOL)[[(NSException *)$eax className] hasPrefix:@"_NSCoreData"])
- I also like to add an action, debugger command, "po $eax" which usually prints out the exception details
$eax is the correct register for the simulator, $r0 works on devices. You can create two separate breakpoints and enable/disable them as appropriate.
See Ignore certain exceptions when using Xcode's All Exceptions breakpoint for the original answer
Solution 3:
I had a similar problem. Eventually, I figured out the problem:
I added an observer to NSManagedObjectContextDidSaveNotification that got freed without removing itself from the notification center. When its memory got assigned to some other object, the notification center tried calling on that object and raised an exception because it couldn't find the right selector. This exception was "invisible" for some reason, but caused CoreData to raise its own exception.
A well placed removeObserver: call fixed the problem.
Hope this may help someone else who encounters this situation.