mbarron
mbarron

Reputation: 285

Is there a better way: my kludgy use of AddingManagedObjectContext?

Problem: kludgy use of AddingManagedObjectContext?

The app is Universal Library Style CoreData. RootTableView has Book Category List, Fiction, Sci-Fi etc. Addition of a book is done on second level BookListTableView via EditButton and then a newly appearing '+' button. The third level displays book details tableview.

When the user touches the '+' button on the second level 'BookList' view, he has already indicated that the book should by default have the category just selected on the home BookCategoryList view. The new book will be an object unknown in the main MOC, and is placed in the addingMOC at the beginning of the insertion operation. I find that if I add the user's desired category, say Sci-Fi, from the mainMOC into the addingMOC, there is an error at save: time, because, as I understand it, a ManagedObject can not exist in two different MOCs.

Because I want to perform this category addition as a convenience to the user, I go through the following work around. I use a new stand-in category with the same category Name, and add it to the new Book's property :

@property (nonatomic, retain) NSSet* categories;

,thus permitting the Books Details Table view in editing mode to display the name of the stand-in category object. Then when the user touches the Save button, just prior to :

[self.addingManagedObjectContext save:&error]

using objectID's, I remove the stand-in category from the new Book and then remove the same from the addingManagedObjectContext itself.

Follow this addingMOC save via:

NSNotificationCenter *dnc = [NSNotificationCenter defaultCenter]; [dnc addObserver:self selector:@selector(addControllerContextDidSave:) name:NSManagedObjectContextDidSaveNotification object: self.addingManagedObjectContext];

the new Book (without category) in the addingMOC is merged into the mainMOC

I then insert the mainMOC's corresponding category to the new book and then save the mainMOC to complete the saveAction.

This works for me, but it feels awkward. Can someone explain where I am wrong and what I am missing? What is the correct and elegant cocoa way to handle this problem?

Thanks, Mark

Upvotes: 0

Views: 50

Answers (1)

Rory O'Bryan
Rory O'Bryan

Reputation: 1904

A managed object can exist in more than one managed object context, or more precisely managed objects that represent the same instance of a given entity can exist in more than one context.

Problems arise when you directly pass a managed object instance from one context to another especially when crossing thread boundaries as you have found.

The correct way to "pass" the managed object is to pass the objectId instead e.g.

//Context 1
NSManagedObjectID *objectID = myObjectInContext1.objectID;

//Context 2
NSManagedObject *myObjectInContext2 = [self.managedObjectContext2 objectWithID:objectID];

Alternatively you could also re-fetch the categories from the persistent store in the second context, which would give you valid category objects, and then pass some other value to indicate which of these objects to use e.g. a category id or title.

Upvotes: 1

Related Questions