Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Solving CoreData error: NULL _cd_rawData but the object is not being turned into a fault

Sometimes while using Core-Data object the app crashes with the error:

CoreData: error: NULL _cd_rawData but the object is not being turned into a fault

From what I could research and read from the internet, is that this happens when a managed object context is passed between two threads and MOCs are not thread safe.

This crash appears whenever I want to access a property from CD object.

If I have Person object and want to access Perosn.name the app could crash with this error (as said before, it happens as far as I can see randomly and I cannot reproduce it, sometimes it would happen 10 times in a row and then not happen for a day or two).

When looking at this problem, it seems that this happens when Person I get and update Person's friends relationship (this is done on the background thread, saved and merged to the main thread MOC).

I would like to get more information about what is happening here, why does this error happen as it seems pretty randomly and if there is any way to prevent the crash.

Below is the code where the context is saved:

__block MyAppDelegate *blockSelf = self;
    dispatch_async(dispatch_get_main_queue(), ^{
        [blockSelf.managedObjectContext performBlock:^{
            [blockSelf.managedObjectContext save:nil];

            dispatch_async(blockSelf.core_data_queue, ^{
                [blockSelf.writerContext performBlock:^{
                    [blockSelf.writerContext save:nil];
                }];
            });
        }];
    });

Update 1 Sometimes when doing the saveContext, I would get the following error:

"Error Domain=NSCocoaErrorDomain Code=1550 "The operation couldn't be completed. (Cocoa error 1550.)

Dangling reference to an invalid object.=null

NSLocalizedDescription=The operation couldn't be completed. (Cocoa error 1550.), NSValidationErrorValue=Relationship 'friends' on managed object (0x201cd340)

UID: <4C1B48C8-6309-4E8E-A590-DED497907A3A>. Asset ID: (null). with objects {(\n '(null)' UID: <(null)>.)}}"

I found this answer from another SO question: "It was due to the object being set created in a different context, note not on a different thread just a different context on the same thread."

Does this seem to be the case, and if it is how could I find where the object is created in the different context that to what I am trying to save to...

like image 302
Ladislav Avatar asked Jan 29 '13 19:01

Ladislav


3 Answers

Hmmm, some things I would change in that code.

  1. Use the error pointers, that is what they are for. You will probably get a solution just from that. Pass in an NSError pointer, check the return from the -save: call and spit out the error to console on a failure.

  2. Your queue management is a little scary. Instead of doing dispatch_async(), change that to -[NSManagedObjectContext performBlock:]. That will guarantee you are on the right thread/queue for the context you are accessing. With the way you have written it there is no guarantee and thus maintainability is low.

Once you make those two changes and you are still failing, update your question with the output from the NSError objects and we can see what is going on.

Update 1

Even though the error is not happening on the saves, you still want to check that return value and the error as it can give us the missing information.

Please reply here if/when you reproduce the crash.

Update 2

Ok, that tends to indicate that you are creating objects in different MOCs and then connecting them through a relationship as you gathered already. Can you post or describe how and when you are creating objects? What MOC you are using?

Can you also post your updated code for saving?

like image 197
Marcus S. Zarra Avatar answered Nov 08 '22 08:11

Marcus S. Zarra


Facing same issue but solved by setting this in Fetchrequest

[fetchrequest setReturnsObjectsAsFaults:NO];
like image 3
Varinder Singh iPhone Dev Avatar answered Nov 08 '22 07:11

Varinder Singh iPhone Dev


I have encountered this problem in my code as well. Later I noticed that I used a managed object created by main thread NSManagedObjectContext in background thread. Since managed object is notoriously thread unsafe so I changed my code and then this bug never appeared again and code works very well. So I guess this is IOS's way of complaining using managed object in threads other than the thread it has been created or fetched.

Hope this help.

like image 2
Roy Li Avatar answered Nov 08 '22 09:11

Roy Li