My application sometimes inserts objects into the context of a managed object, which need not be persisted. For example, when I run the add entity mod, I create a managed entity and assign it to a modal. If the user saves this modal mode, I keep the context. If it cancels, I delete the object and saving is not required.
Now I have introduced an import function that switches to my application (using a URL scheme) and adds an object. Since one of these modals may be open, it is unsafe to maintain context at this point. The temporary object created for the modal will be saved even if the user cancels, and there is no guarantee that the deletion (from the cancel operation) will be saved later - the user can exit the application.
Similarly, I cannot just save when my application terminates. If the modality is open at this point, the temporary object will not be saved correctly.
To solve this problem, I am trying to use a child context, as discussed here . After reading everything that I could find on SO, I had a few questions:
What type of concurrency should be used for each context? Remember that I am not doing this for performance / threading benefits. I know that I cannot use NSConfinementConcurrencyType for the main context if it has child contexts, but I'm not sure which of the other two options works best. As for the children's context, does it need to be matched? Or can I use confinement type here? I tried various combinations and everything seems to work fine, but I would like to know what suits my requirements.
(side issue) Why can I make this work if I use the iVar class? I thought that I should be able to declare a temporary context in the method where it was created, and then later refer to it using entity.managedObjectContext. But, unfortunately, by the time I come to him? This is fixed if I use iVar instead to store the link.
What is the correct way or propagation of changes in the main context? I saw various comments using different blocked implementations in each of the contexts. Does it depend on my type of concurrency? My current version is:
//save the new entity in the temporary context NSError *error = nil; if (![myObject.managedObjectContext save:&error]) {NSLog(@"Error - unable to save new object in its (temporary) context");} //propogate the save to the main context [self.mainContext performBlock:^{ NSError *error2 = nil; if (![self.mainContext save:&error2]) {NSLog(@"Error - unable to merge new entity into main context");} }];
When my user saves, he sends a message to his delegate (my main view controller). The delegate is passed the object that was added, and it must find the same object in the main context. But when I look for it in the main context, it is not found. There is an object in the main context - I can register its data and confirm that it is - but the address is different? If this should happen (why?), How can I find the added object in the main context after saving?
Thank you for understanding. Sorry for the long, frequent question, but I thought that someone would probably address all these issues earlier.
ios objective-c cocoa core-data nsmanagedobjectcontext
Ben Packard Jan 11 '13 at 18:20 2013-01-11 18:20
source share