I am working on a project where I am doing a mass delete of a number of NSManagedObjects (MO) that I retrieve from Core Data. When I iterate through this collection of MO's, I am also retrieving OTHER MO's by calling a fetch method DURING the iteration of the initial collection of MO's.
If during this iteration process, an object is found from the fetch request, the MO is deleted. I realize that this is a poor design of the architecture, as these MO's should in fact be having inverse relationships with one another, and therefore via a cascade delete rule, all of these objects would easily be deleted. This unfortunately is not the case, and it would be too difficult to go back and make these fixes, which is why I am here.
Also, I realize that this scenario which I am describing should be using a parent-child NSManagedObjectContext to do things correct, and of course, to avoid crashes from occurring. I am unsure how to implement this given the architecture I am working with. Here is an example of the code I am working with:
- (void)massDelete {
...
NSArray *objectsToPurge = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
if (objectsToPurge) {
[objectsToPurge enumerateObjectsUsingBlock:^(MyMO *mo, NSUInteger idx, BOOL *stop) {
OtherMO *otherMO = [self fetchOtherMO:mo];
if (otherMO) {
[self.managedObjectContext deleteObject:otherMO];
}
[self.managedObjectContext deleteObject:mo];
}];
}
[self.managedObjectContext save:&purgeError];
}
- (OtherMO *)fetchOtherMO:(MyMO *)mo {
NSManagedObjectContext *context = [[MySingleton sharedInstance] managedObjectContext];
NSError *error;
// Create fetch request
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"OtherMO" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
// Create predicate
NSPredicate *pred = [NSPredicate predicateWithFormat:@"myMO == %@", mo];
[fetchRequest setPredicate:pred];
NSArray *items = [context executeFetchRequest:fetchRequest error:&error];
if ([items count]>0) {
return [items firstObject];
} else {
return nil;
}
}
Like I said, I realize that I am using two separate NSManagedObjectContexts here, and I need to implement a Parent-Child construct, but am unsure how to do this. Given that I can't do anything about the Core Data architecture, and given this is the scenario I am working with, what would be the best solution for my problem?
I think it not require two MOC, you are able to solve it by one. Just pass it as a parameter to the
fetchOtherMOByMyMo:(MyMo *)mo onContext:(NSManagedObjectContext *)context.
And you forget to use
performBlock:
Check, it should work without crashing: