• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: (simple?) CoreData question :-)
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: (simple?) CoreData question :-)


  • Subject: Re: (simple?) CoreData question :-)
  • From: Melissa Turner <email@hidden>
  • Date: Fri, 3 Mar 2006 13:35:10 -0800

The answer depends on the user visible semantics you want in the second MOC, and the state of the objects in the second MOC.

There is no inter-context notification done automatically by CoreData, so in all cases, the first MOC will post a NSManagedObjectContextDidSave notification that your application should register for and use as the trigger for whatever actions it needs to take. This notification contains information about deleted objects, but also about changed objects, which will also need to be handled since these changes may be the result of the delete (most of the ways this can happen involve transient relationships or fetched properties, but it is possible). If you had this problem between processes, OSX & Cocoa provide a number of other mechanisms you can use to increase the scope of CoreData change notifications like NSDistributedNotificationCenter and kqueues.

There are multiple axes you consider when deciding how you want to handle your delete notification. The important ones are: what other changes exist in the second MOC; whether or not the instance of the object that was deleted has changes in the second MOC; and whether or not changes in the second MOC can be undone. These are somewhat orthogonal, and what actions you take to synchronize the contexts depend on the semantics of your application.

1) The simplest case is when the object itself has not changed in the second MOC and you don't have to worry about undo; in this case, you can just delete the object. The next time this context saves, the framework will notice that you're trying to re-delete something, ignore the optimistic locking warning, and life will go on happily.

2) The next simplest is when you don't care about the contents of the second MOC: you can simply reset it and refetch any data you need after the reset. This will reset the undo stack as well, and the deleted object is now gone. The only trick here is figuring out what data to refetch - this can be done by collecting the oids before you reset, and using those to reload once the reset has happened (you'll need to exclude the deleted oids, and probably you want to do fetch requests with IN predicates to unforseen weirdness and problems will not being able to fulfill faults for deleted oids).

Things start getting complicated after this.

3) If the object has changed in the second MOC, but you don't care about undo, your response depends on what it means for the semantics of your application. If the object that was deleted in MOC1 has changes in MOC2, should it be deleted from MOC2 as well? Or should it be resurrected and the changes saved? What happens if the original deletion triggered a cascade delete for objects that have not been faulted into the second MOC? What if the object was deleted as part of a cascade delete? 3a) The simplest answer here is to just discard the changes by deleting the object.
3b) If the object is standalone, you can set the merge policy on the context to NSMergePolicyOverwrite. This will cause the changes in the second context to overwrite the delete in the database. Note that this will cause ALL changes in MOC2 to overwrite any changes made in MOC1.


These are the best solutions, and are least likely to leave your object graph in some unsustainable state as a result of something you missed. For the brave of heart (or the utterly insane) continue reading.

3c) If the object isn't standalone, and for some reason you want to save those changes, the best you're likely to be able to do is to resurrect the part of the graph that had been loaded into the second MOC, which may or may not make sense in the context of your application. This is again done by setting the merge policy to NSMergePolicyOverwrite, but requires some up-front application design, and some meddling with the objects in the 'deleted' object's relationships. In order for the world to make some amount of sense later, you need to automatically fault in any relationships that might need to be resurrected when you fault in the object. Then, when you get a delete notification, you'll need to make the context think all the objects related to the 'deleted' object have changed, so that they will be saved as well. This is going to bloat your application's memory use, since you'll end up with possibly irrelevant data sitting around as a precaution against something that may not happen, and if you're not careful, you can end up with your database in a hybrid state where it's neither what MOC1 tried to create, nor what MOC2 would expect (you missed a relationship somewhere and you now have partial relationships, or orphaned nodes). ****This is probably a bad idea.****

4) The second worst of all worlds is when you have changes to other objects you can't blow away in the second MOC, the object itself has changes that you are willing to discard, and you care about undo. You can't reset the context, because that loses the changes. If you delete the object, the delete will get pushed onto the undo stack and will be undoable, so the user could undo, resave, and run into the semantic problems I talk about in part 3, only worse because you haven't planned for them. The only real way to solve this is to keep track - separately, in your application code - of the objects which are changed as a result of the delete. You then need to track user undo events, and when the user undoes past a delete, you can then 'rerun' the deletion. ****This is going to get messy and inefficient very quickly if there are a significant number of changes being propagated.***

5) Worst case is you have changes to other objects you can't/won't discard, the object has changes you want to keep, and you care about undo. There's probably a way to do it, it will be insanely ugly and complicated and I'm not going to provide any rope here.

If you find yourself in cases 3c-5, you should probably just redesign your application's model to bring you into 1-3b.

+Melissa

On Mar 2, 2006, at 10:19, Mr. Guillaume Christian Rager wrote:

Hey

I have core data application that uses SQLite store.
The persistent store coordinator is shared between 2 MOCs.

When the user deletes an object in MOC moc1, the deletion is seen by NSArrayControllers and the tableview are refreshed.

How can i inform the second MOC that the object with the same objectID (i'll use objectWithObjectID:) has been removed? is it up to me to inform the second MOC app that an object has been deleted in the first MOC? should i remove this object again (using objectWithObjectID:) in the second MOC ?

thanks

Guillaume

-----------
GUMITECH - France
http://www.gumitech.com

"Chaud cocoa, chaud chocolat !"
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden

_______________________________________________ Do not post admin requests to the list. They will be ignored. Cocoa-dev mailing list (email@hidden) Help/Unsubscribe/Update your Subscription: This email sent to email@hidden
References: 
 >(simple?) CoreData question :-) (From: "Mr. Guillaume Christian Rager" <email@hidden>)

  • Prev by Date: Re: I can't figure out how to use NSIndexSet
  • Next by Date: Re: Bezier drawing tool suggestions?
  • Previous by thread: Re: (simple?) CoreData question :-)
  • Next by thread: Re: text storage aggregator (again)
  • Index(es):
    • Date
    • Thread