Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Core Data could not fulfill a fault.." error

Tags:

core-data

I am developing an application in cocoa. I am facing a critical problem.

I am deleting entries of an object named "Directory" in Core Data using the following code:

NSEnumerator *tempDirectories = [[folderArrayController arrangedObjects] objectEnumerator];
id tempDirectory;
while (tempDirectory = [tempDirectories nextObject]){
    [managedObjectContext deleteObject:tempDirectory];
}

But sometimes an exception like "Core Data could not fulfill a fault.." occurs while trying to save after deletion. I am using the code [managedObjectContext save];

I am new in Core Data... Looking forward to a solution.

like image 963
MobX Avatar asked Aug 12 '09 09:08

MobX


People also ask

What is data fault in Core Data?

From the moment we ask for the value of a property of one of the records, Core Data jumps into action and fetches the data from the persistent store. This is better known as firing a Core Data fault.

How do I clear my Core Data?

One approach to delete everything and reset Core Data is to destroy the persistent store. Deleting and re-creating the persistent store will delete all objects in Core Data.

Should I enable Core Data?

The next time you need to store data, you should have a better idea of your options. Core Data is unnecessary for random pieces of unrelated data, but it's a perfect fit for a large, relational data set. The defaults system is ideal for small, random pieces of unrelated data, such as settings or the user's preferences.

What is Nsmanagedobjectcontext in Core Data?

An object space to manipulate and track changes to managed objects.


1 Answers

This is an old question, I have struggled resolving this for some time now. So, thought it would be best to document it.

As Weichsel above mentioned, the Apple documentation rightly points out reason for this exception. But it is a hectic job to identify the module due to which the NSManagedObject subclass' object is being retained (if 1st cited reason in the documentation is the root cause of the problem).

So, I started out by identifying the parts of my code which was retaining the NSManagedObject, instead I retained the NSManagedObjectID and create the managed object out of it whenever needed. The discussion in similar lines can be found in Restkit documentation:

  1. https://github.com/RestKit/RestKit/commit/170060549f44ee5a822ac3e93668dad3b396dc39
  2. https://github.com/RestKit/RestKit/issues/611#issuecomment-4858605

Updated my setter and getter so that the interface with rest of the modules remain same while internally we now depend upon NSManagedObjectID and avoid retaining of NSManageObject:

-(CSTaskAbstract*)task
{
    CSTaskAbstract *theTask = nil;
    if (self.taskObjectID)
    {
        NSManagedObjectContext *moc = [(CSAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
        // https://github.com/RestKit/RestKit/commit/170060549f44ee5a822ac3e93668dad3b396dc39 &
        // https://github.com/RestKit/RestKit/issues/611#issuecomment-4858605
        NSError *theError = nil;
        NSManagedObject *theObject = [moc existingObjectWithID:self.taskObjectID
                                                         error:&theError];
        if ([theObject isKindOfClass:[CSTaskAbstract class]])
        {
            theTask = (CSTaskAbstract*)theObject;
        }
    }
    return theTask;
}
-(void)setTask:(CSTaskAbstract *)inTask
{
    if (inTask!=self.task)
    {
        // Consequences of retaining a MO when it is detached from its MOC
        [self setTaskObjectID:[inTask objectID]];
    }
}

The above is the first half of the problem solved. We need to find out dependency in suspicious parts of our app and eliminate.

There was some other problem too, instruments -> allocations is a good source to find out which modules are actually retaining the managed objects, the exception object would have details about which managed object is creating the problem, filter results for that object as shown below:

Instruments - Allocations

We were performing KVO on a managed object. KVO retains the observed managed object and hence the exception is thrown and it's back trace would not be from within our project. These are very hard to debug but guess work and tracking the object's allocation and retain-release cycle will surely help. I removed the KVO observation part and it all started working.

like image 53
Raj Pawan Gumdal Avatar answered Sep 28 '22 00:09

Raj Pawan Gumdal