The correct way to achieve this sort of thing is with a new managed object context. You create a managed object context with the same persistent store:
NSManagedObjectContext *tempContext = [[[NSManagedObjectContext alloc] init] autorelease];
[tempContext setPersistentStore:[originalContext persistentStore]];
Then you add new objects, mutate them, etc.
When it comes time to save, you need to call [tempContext save:...] on the tempContext, and handle the save notification to merge that into your original context. To discard the objects, just release this temporary context and forget about it.
So when you save the temporary context, the changes are persisted to the store, and you just need to get those changes back into your main context:
/* Called when the temp context is saved */
- (void)tempContextSaved:(NSNotification *)notification {
/* Merge the changes into the original managed object context */
[originalContext mergeChangesFromContextDidSaveNotification:notification];
}
// Here's where we do the save itself
// Add the notification handler
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(tempContextSaved:)
name:NSManagedObjectContextDidSaveNotification
object:tempContext];
// Save
[tempContext save:NULL];
// Remove the handler again
[[NSNotificationCenter defaultCenter] removeObserver:self
name:NSManagedObjectContextDidSaveNotification
object:tempContext];
This is also the way you should handle multi-threaded core data operations. One context per thread.
If you need to access existing objects from this temporary context (to add relations etc.) then you need to use the object's ID to get a new instance like this:
NSManagedObject *objectInOriginalContext = ...;
NSManagedObject *objectInTemporaryContext = [tempContext objectWithID:[objectInOriginalContext objectID]];
If you try to use an NSManagedObject
in the wrong context you will get exceptions while saving.