Let's say I have a NSManagedObject named «Picture» that I have created via RestKit. I'm uploading the actual picture file content through a NSOperation. That NSOperation is tracking the upload progress, and saving it in the «progress» attribute of the Picture object.
if(![self isCancelled]) {
Picture *pic = [Picture findFirstByAttribute:@"pictureId" withValue:self.pictureId];
if(![pic isDeleted]) {
pic.progress = [NSNumber numberWithFloat:progress];
[[RKObjectManager sharedManager].objectStore save:NULL];
}
}
My view controller is displaying a list of Picture objects, with the help of a NSFetchedResultsController. Upload works great, RestKit is doing the thread safety and the merge back to the main NSManagedObjectContext, so the UI is displaying the upload progress as expected.
Imagine now that while uploading the picture the user presses the «cancel» cross, which is also supposed to delete the Picture object. In the controller, I'm calling a cancel on the NSOperation, which effectively stops the running the operation within milliseconds, and the object is deleted from CoreData on the main thread.
[uploadOperation cancel];
Picture *pic = [Picture findFirstByAttribute:@"pictureId" withValue:self.pictureId];
[pic deleteEntity];
[[RKObjectManager sharedManager].objectStore save:NULL];
Traces show that I get a NSFetchedResultsChangeDelete on my NSFetchedResultsControllerDelegate as expected. However it is immediately followed by a NSFetchedResultsChangeInsert and a NSFetchedResultsChangeUpdate, because the saving of the progress is made really frequently by the NSOperation. It seems that the NSManagedObjectContext used by the NSOperation is out of sync. It doesn't know that the Picture object is deleted, the call to save: causes an insert and an update.
So in my UI (and in DB), my Picture object remains while it's supposed to be deleted.
Looking at RKManagedObjectStore, it seems that merges are made from background threads (NSOperation) to main thread (my view controller) but not the opposite way.
What's the best approach to fix this issue ?