NSManagedObjectContext save doesn't crash but breaks on objc_exception_throw
Asked Answered
M

5

7

I am having the same issue described at this address http://www.cocoabuilder.com/archive/cocoa/288659-iphone-nsmanagedobjectcontext-save-doesn-crash-but-breaks-on-objc-exception-throw.html

I am debugging an application that uses Core Data with multithreading, and I have a breakpoint on objc_exception_throw and it hits this breakpoint in the call to save. (line 2 in code)

        NSError *error = nil;
        [self.managedObjectContext save:&error];
        if (error) {
            NSLog(@"Error : %@",error);
        }

I don't have any thing that is logged. I am using Xcode 4 with ios 4.0 -> 4.3. I think this is not related to Xcode/iOS version.

Morey answered 10/8, 2011 at 8:7 Comment(7)
Try removing the breakpoint and see if anything is logged.Affiliation
Nothing is logged when I remove the breakpointMorey
try changing ur condition to if(error!=nil). Doesnt seem like different but it is...personal experiencePancratium
It's The same thing, I also tried if (![self..managedObjectContext save:&error]) , and no resultMorey
you are mixing contexts and threads, post how you setup your nsmanagedobjectcontext plus the thread operations and someone might be able to help.Towers
So what is the exception that's being thrown?Fibrosis
I might get wrong, but I understood there's not real 'exception' being thrown, usually when using the xcode simulator the app doesn't crash, but stop responding with "objc_exception_throw" shown in console. The program stop at line 2, following line doesn't get even called. It just seems a memory related question.Hideous
H
5
  • First, when using multithread with CoreData I had few problems when passing NSManagedObject around the app. Instead, as documented by Apple, I end up passing NSManagedObjectID and reconstruct the full object.
  • Second, when you don't have anything logged, it is likely related to memory issues, try to run the profiler especially, but not only, looking for 'Zombie', it should tell you more.
  • Finally, make sure you have initialized the context correctly, I had similiar problem because the model from momd file was not found and not loaded.
Hideous answered 10/8, 2011 at 12:52 Comment(2)
Wondering what was the cause in your situation? I am seeing the same thing. At the point of the exception I get warning: Attempting to create USE_BLOCK_IN_FRAME variable with block that isn't in the frame. The weird thing is it doesn't happen all the time, which seems to point towards threading. So any experience you can post would be great!Monreal
You can trigger this exception by updating an object that was deleted from the persistent store via another context. The exception seems to be handled internally by skipping the dud object.Solace
G
7

Looking at this answer reveals that CoreData internally uses exceptions to manage their program flow. Thats why the debugger breaks at objc_exception_throw. As far as I know there is no way to disable this.

EDIT: Since then, there is now a solution to ignore these exceptions: Ignore certain exceptions when using Xcode's All Exceptions breakpoint

BTW: Do not check on error but use the returned BOOL value to ensure success of your save call. The correct way of doing this would be:

NSError *error = nil;
BOOL success = [self.managedObjectContext save:&error];
if (!success) {
    NSLog(@"Error : %@",error);
}
Gambrel answered 5/11, 2012 at 16:45 Comment(1)
Long time since my answer. Nowadays I normally use the following test: if (!success || error) { and a solution to the exception problem is also available.Gambrel
H
5
  • First, when using multithread with CoreData I had few problems when passing NSManagedObject around the app. Instead, as documented by Apple, I end up passing NSManagedObjectID and reconstruct the full object.
  • Second, when you don't have anything logged, it is likely related to memory issues, try to run the profiler especially, but not only, looking for 'Zombie', it should tell you more.
  • Finally, make sure you have initialized the context correctly, I had similiar problem because the model from momd file was not found and not loaded.
Hideous answered 10/8, 2011 at 12:52 Comment(2)
Wondering what was the cause in your situation? I am seeing the same thing. At the point of the exception I get warning: Attempting to create USE_BLOCK_IN_FRAME variable with block that isn't in the frame. The weird thing is it doesn't happen all the time, which seems to point towards threading. So any experience you can post would be great!Monreal
You can trigger this exception by updating an object that was deleted from the persistent store via another context. The exception seems to be handled internally by skipping the dud object.Solace
S
1

I had a similar problem, eventually it turned out to be because of an observer of NSManagedObjectContextDidSaveNotification that was deallocated without removing itself from the notification center. It seems that the CoreData exception "hides" the unknown selector exception that is raised when the notification center tries notifying whatever object occupies the memory freed by the registered (but deallocated) observer.

Sacrilegious answered 25/2, 2012 at 16:18 Comment(0)
P
1

Recently I ran into the same issue: app crashing without any log, when trying to save managedObjectContext.

In my case there was a completely different cause from mentioned above:
Make sure you do not have DB Manager open on your mac, that could be locking the persistent data store.

This will (apparently) also kill the Core Date stack, without throwing any visible errors in code or in log.

Turned out I had some unsaved changes, which made the DB Manager lock the store. Closing the DB Manager fixed the issue. Simple and stupid error, but took me hours to figure out.

Pfeifer answered 8/11, 2015 at 23:5 Comment(0)
T
0

I happened to meet this problem, and after long time debug I found it's because of a duplicate declaration of the NSError* error, may you had another NSError* error in the outer scope, like:

NSError* error = nil;

Some code

if (!error)
{
    NSError* error = nil;
    // your code
}

Then the error will be nil although in fact there is a exception.

Telemachus answered 30/4, 2012 at 5:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.