Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Deal with Temporary NSManagedObject instances?

I need to create NSManagedObject instances, do some stuff with them and then trash them or store to sqlite db. The problem is, I cannot create instances of NSManagedObject unconnected to NSManagedObjectContext and this means I have to clear up somehow after I decide that I don't need some of the objects in my db.

To deal with it, I have created an in-memory store using the same coordinator and I'm placing temporary objects there by using assignObject:toPersistentStore. Now, how do I ensure that these temporary objects don't get to the data, which I fetch from the common to both stores context? Or do I have to create separate contexts for such a task?


UPD:

Now I'm thinking about making separate context for in-memory store. How do I move objects from one context to another? Just using [context insertObject:]? Will it work OK in this setup? If I insert one object from the graph of objects, does the whole graph also get inserted into context?

like image 231
fspirit Avatar asked Jul 15 '10 13:07

fspirit


People also ask

What is the purpose of NSManagedObjectContext?

A managed object context is an instance of NSManagedObjectContext . Its primary responsibility is to manage a collection of managed objects. These managed objects represent an internally consistent view of one or more persistent stores.

How do I set up NSManagedObject?

From the Xcode menu bar, choose Editor > Create NSManagedObject Subclass. Select your data model, then the appropriate entity, and choose where to save the files. Xcode places both class and properties files into your project.


2 Answers

NOTE: This answer is very old. See comments for full history. My recommendation has since changed and I no longer recommend using unassociated NSManagedObject instances. My current recommendation is to use temporary child NSManagedObjectContext instances.

Original Answer

The easiest way to do this is to create your NSManagedObject instances without an associated NSManagedObjectContext.

NSEntityDescription *entity = [NSEntityDescription entityForName:@"MyEntity" inManagedObjectContext:myMOC]; NSManagedObject *unassociatedObject = [[NSManagedObject alloc] initWithEntity:entity insertIntoManagedObjectContext:nil]; 

Then when you want to save it:

[myMOC insertObject:unassociatedObject]; NSError *error = nil; if (![myMoc save:&error]) {   //Respond to the error } 
like image 123
Marcus S. Zarra Avatar answered Nov 21 '22 10:11

Marcus S. Zarra


iOS5 provides a simpler alternative to Mike Weller's answer. Instead use a child NSManagedObjectContext. It removes the need to trampoline through NSNotificationCenter

To create a child context:

NSManagedObjectContext *childContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType]; childContext.parentContext = myMangedObjectContext; 

Then create your objects using the child context:

NSManagedObject *o = [NSEntityDescription insertNewObjectForEntityForName:@"MyObject" inManagedObjectContext:childContext]; 

The changes are only applied when the child context is saved. So to discard the changes just do not save.

There is still a limitation on relationships. ie You can't create relationships to objects in other contexts. To get around this use objectID's, to get the object from the child context. eg.

NSManagedObjectID *mid = [myManagedObject objectID]; MyManagedObject *mySafeManagedObject = [childContext objectWithID:mid]; object.relationship=mySafeManagedObject; 

Note, saving the child context applies the changes to the parent context. Saving the parent context persists the changes.

See wwdc 2012 session 214 for a full explanation.

like image 33
railwayparade Avatar answered Nov 21 '22 10:11

railwayparade