Take a look at the performBlock and performBlockAndWait methods on NSManagedObjectContext.
I have been favoring using NSPrivateQueueConcurrencyType even for my UI bound managed object contexts because it avoids exactly this situation. For example you could do something like this:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
NSManagedObjectContext *context = [self managedObjectContext];
if (editingStyle == UITableViewCellEditingStyleDelete)
{
NSManagedObject *m = [self.tests objectAtIndex:indexPath.row];
[context performBlock:^{
[context deleteObject:m];
if (![context save:&error]) {
//Note: You should really do something more useful than log this
NSLog(@"Can't Delete! %@ %@", error, [error localizedDescription]);
}
}];
[self.tests removeObjectAtIndex:indexPath.row];
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
The performBlock call is asynchronous (as opposed to its synchronous counterpart performBlockAndWait) which will allow the tableView update to proceed as the context is busy saving on a separate thread.
As an aside, your managed object context instance should not change very often. It is common for small applications to only allocate a single instance of NSManagedObjectContxt during their lifecycle.