How do we prevent "CoreData could not fulfill a fault"?
Asked Answered
R

1

6

We get "CoreData could not fulfill a fault" every once in a while. We have read through the Apple documentation but are unclear on what is allowed to be retained. We have been very careful about creating one context per thread, etc. However, one thing our app is doing is we are retaining NSManagedObjects on our UIViewControllers (usually via a NSArray or NSDictionary). I'm guessing what's going on is the object relationships are changing and we are not handling the appropriate notification.

Does anyone have any suggestions on the better design with regards to Core Data? When we get the error, I cannot see that we actually deleted anything from the context to cause the fault. Is it necessary to handle NSManagedObjectContextObjectsDidChangeNotification on our UIViewControllers if they are retaining state? Any suggestions would be appreciated.

Raffarty answered 6/8, 2011 at 21:30 Comment(1)
We had a view that was not getting released which had references to NSManagedObjects after they were deleted. Very hard to find.Raffarty
D
5

You can register for change notifications in Core Data. This will allow you to update your managed objects when they change. See the Core Data Docs for more info. You're going to be interested in 2 methods to register and respond to changes:

  [NSNotificationCenter defaultCenter] addObserver:self
                                          selector:@selector(mergeChanges:)
                                              name:NSManagedObjectContextDidSaveNotification
                                            object:(your NSManagedObjectContext)];

The mergeChanges selector (your method) will call the following method to synchronize any changes from other threads. It will look something like this:

- (void)mergeChanges:(NSNotification *)notification{
  AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
  NSManagedObjectContext *context = [appDelegate managedObjectContext];

  // Merge changes into the default context on the main thread
  [context performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:)
                            withObject:notification
                         waitUntilDone:YES];  
}
Demonography answered 10/8, 2011 at 14:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.