NSManagedObjectContext: exception breakpoint stops at save: method, but no log/crash/error

Objective CCore Data

Objective C Problem Overview


I'm using CoreData in a multi-threaded iOS-app, and everything seems to work fine - unless I switch on the exception breakpoint in XCode. Whenever I do some CoreData-work, the breakpoint stops at the save:-method on NSManagedObjectContext - but the NSError is nil afterwards. I also have nothing in the log (except: Catchpoint 2 (exception thrown).), the app doesn't crash... So it's pretty hard to tell what's going wrong.

The only clue I have is that I have a single object in updatedObjects: in my NSManagedObjectContext - but there seems nothing wrong with it.

My question is very similar to this question on stackoverflow , but the only answer there doesn't help me; I'm pretty sure that I've got everything covered there.

What could be wrong here? Or are there other possibilities to get some error information?

Thank you very much!

EDIT: showing code is pretty difficult. I'm loading objects with objectID, edit and store them in the context assigned to the current thread. I already checked - the context is always correct for the current thread; each thread has its own context, that shouldn't be the problem. It would be even helpful if only someone could tell me how to get more information from that error/exception - or if I have to care about it after all. It seems to me as if the exception is catched within the `save´-method, so probably its a "normal" behaviour?

Objective C Solutions


Solution 1 - Objective C

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 - Objective C

You can avoid these useless breaks; as others have pointed out this is normal CoreData behavior (but highly annoying!)

  1. Remove the "All Objective-C Exceptions" breakpoint
  2. Add a Symbolic Breakpoint on objc_exception_throw
  3. Set a Condition on the Breakpoint to (BOOL)(! (BOOL)[[(NSException *)$eax className] hasPrefix:@"_NSCoreData"])
  4. 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 https://stackoverflow.com/questions/14370632/ for the original answer

Solution 3 - Objective C

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.

Solution 4 - Objective C

I had a similar issue occur in my code. I finally discovered that the issue was due to my model having changed, and the EncryptedCoreData NSPersistentStoreCoordinator I was using wasn't set up for automatic migration, as I had been expecting with MagicalRecord in the past.

The only symptom was this break point, without any other messages. It was solved (temporarily) by deleting and reinstalling the app and permanently by adding model versions and the appropriate key (NSMigratePersistentStoresAutomaticallyOption: true, NSInferMappingModelAutomaticallyOption: true) to my stack setup.

Solution 5 - Objective C

I struggled with the same problem and what i found is the coordinator will throw an exception when there is a merge problem. I have removed my merge policy (default is the error) and after that the error pointer is no longer nil when you call save. That also gave me confidence that my code is ok.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionswalknerView Question on Stackoverflow
Solution 1 - Objective CDaniel EggertView Answer on Stackoverflow
Solution 2 - Objective CrussbishopView Answer on Stackoverflow
Solution 3 - Objective CYonatView Answer on Stackoverflow
Solution 4 - Objective CsschaleView Answer on Stackoverflow
Solution 5 - Objective CLucian BobocView Answer on Stackoverflow