I have an operation object which creates it's own Managed Object Context. The operation object performs calculation basically to take off load from main thread while main thread concentrates on the UI aspect. This operation object's MOC shares a common persistent store across the application.
It sometimes happens such that, while the operation is being performed, the MOC of main thread is notified of changes in backend. So, I try to merge the changes of MOC, where some of the deletions in model objects might happen. In some rare cases, as I observe, the operation object might not have been realized yet and they are in fault state and at the same time main thread stores the changes into MOC (and to persistent store). My app is crashing in such scenario.
As per the standard texts, I have a dedicated MOC for my threads and as per my understanding, the data for faults should be accessed from the MOC of the thread. Does it make a difference in accessing fault requests from MOC of the thread, when say, the same object might have been deleted from the store?
Please see this stack trace:
What would be a better way of handling this?
I do understand from this post: https://stackoverflow.com/a/5722914/260665 that the managed object context of thread is not aware of the changes underlying the store and the faulted objects are expected to exist in the store. So, better it would be to either:
Update the collection of objects in the thread when there are any underlying changes (deletion) in the store by using the
NSManagedObjectContextDidSaveNotification
notification (From: https://stackoverflow.com/a/5722914/260665)Check whether the
NSManagedObject
's record exists in the store before trying to access it's properties by using-existingObjectWithID
on the MOC (From: https://stackoverflow.com/a/14297708/260665)Handle exceptions in code? (Last resort, from: https://stackoverflow.com/a/15361906/260665)
I cannot possibly go ahead with solutions 1 & 2 for it's not the NSManagedObject's properties directly am accessing, I have NSFetchedResultController which have sort descriptors inside which the app is crashing:
-(NSMutableArray*)fetchedTaskObjects
{
if (nil==fetchedTaskObjects_ && self.taskLocalFetchedResultsController && self.persistantTaskFetchedResultsController)
{
NSArray *allNonPersistantTasks = [self.taskLocalFetchedResultsController fetchedObjects];
NSArray *allPersistantTasks = [self.persistantTaskFetchedResultsController fetchedObjects];
fetchedTaskObjects_ = [[NSMutableArray alloc] init];
[fetchedTaskObjects_ addObjectsFromArray:allNonPersistantTasks];
[fetchedTaskObjects_ addObjectsFromArray:allPersistantTasks];
NSSortDescriptor *tasksSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"self.mockTaskCounter"
ascending:YES];
NSSortDescriptor *shortTextSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"self.shortText"
ascending:YES];
NSSortDescriptor *headerTextSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"self.accountAssignmentText"
ascending:YES];
[fetchedTaskObjects_ sortUsingDescriptors:[NSArray arrayWithObjects:tasksSortDescriptor, shortTextSortDescriptor, headerTextSortDescriptor, nil]];
}
return fetchedTaskObjects_;
}
So any suggestions of finding the solution in a right way?
Edit: The error (exception) which I am getting:
CoreData could not fulfill a fault for '0x2b0298a0 <x-coredata://E7E91AFC-5BE6-4996-B28F-92CD115A5D0A/CSTaskRegister/p14746>'
Which line it crashes?
It crashes in any one of the sort descriptors where the internal property of the faluted Managed object is tried to access by the sort descriptors for sorting purpose. Since it is a thread, we are not sure when exactly the underlying object is deleted in the store. So, the thread crash sometimes also occurs in my statistics calculation code.
Why am combining the result of two FRC?
Because, the project initially started out with different MOCs for these 2 cases, now though the MOC is single the differentiation still remains. But I don't think it is a problem to have discrete FRCs with it's own purpose.