Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 942
swalkner Avatar asked Dec 01 '11 07:12

swalkner


2 Answers

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. } 
like image 156
Daniel Eggert Avatar answered Sep 19 '22 13:09

Daniel Eggert


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 Ignore certain exceptions when using Xcode's All Exceptions breakpoint for the original answer

like image 23
russbishop Avatar answered Sep 17 '22 13:09

russbishop