Thanks for your advice, Ben.

I submitted a Bug Report.  Problem ID is: 6624874

And for the sake of the list archive audience, here's the text, which summarizes this whole thread...

Summary: In many applications, auxiliary views or objects are interested in changes that occur to Core Data managed objects. In Cocoa, such information is ordinarily obtained by notifications or key- value observing (KVO). But using either technique to obtain information about managed objects is incomplete or difficult.

Steps to Reproduce:
Build an Core Data application such as Apple's DepartmentAndEmployees sample project. Add some auxiliary views or objects which would like to be informed of changes to some of the managed objects. For example, a) An OrgChart view wants to be informed whenever the directReports of any Employee changes. b) A Payroll object is interested wants to be informed whenever the 'salary' of any Employee changes, or an Employee is added or deleted. c) A DuplicateFirstNames object wants to be informed whenever the firstName of an Employee changes, or an Employee is added or deleted.

Expected Results:
There should be an easy way to register for notifications or use KVO to be informed of the desired changes.

Actual Results:
There appear to be three solutions available to get the desired information, but none of them are very practical.

Solution 1. Use KVO. Although adding observers can be done rather systematically, in awakeFromInsert and awakeFromFetch, removing observers must be done (1) when deallocating the moc and (2) in the managed object's -dealloc method (which is not recommended for subclassing). The latter is to catch objects still on the undo stack or elsewhere, and requires checking that the observer has not already been removed by the former. Removing the observers when deallocating the moc is also an ugly process -- you fetch all objects and send each one a "-removeYourObservers" message, if they respond. Another alternative considered is to remove the observer in -didTurnIntoFault, but this is not acceptable because -didTurnIntoFault may be invoked when an object is deleted, but if delete is reversed by Undo, and faulted back in, there is no hook available (i.e. -didUnturnIntoFault) for the programmer to know that the object is back so that the observer can be restored as it must be.

Solution 2. Use Custom Setters. For each key/value in each object that is to be observed, implement a custom setter, and in each such custom setter post a notification of the value change. This is not too bad with attributes, because there is only one setter per attribute. But for to-many relations you need to override the four (or is it five) set mutator methods in order to cover all the possible ways in which the relationship may be changed. What if more mutator methods are added in some future version of Mac OS? This requires much code and seems quite fragile.

Solution 3. Use NSManagedObjectContextObjectsDidChangeNotification. Interested objects can register for NSManagedObjectContextObjectsDidChangeNotification. The information you get in the notification is adequate if objects are added or deleted, but not for updated objects because it does not tell you the key of the value which changed that caused the notification. You can send -changedValues to the object, but this will return ^all^ key/ values that were changed since the last time the managed object context was saved. So you either need to have some kind of memory to filter out the repititions, or process the same change multiple times. The former is a kludge, and may be too expensive, and the latter may be unacceptable, for example, if the user is to be alerted when a change occurs.

Notes:
My favored solution might be to enhance NSManagedObjectContextObjectsDidChangeNotification so that it included the key/value immediately responsible for the change in Updated objects. Then, only one notification needs to be registered for, and only one method needs to be written, the selector for this notification, in which the programmer would filter out whatever changes are relevant and forward appropriate messages to the interested objects or views.

_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to