Re: Core Data: Custom to-many relationship setter not being invoked
Re: Core Data: Custom to-many relationship setter not being invoked
- Subject: Re: Core Data: Custom to-many relationship setter not being invoked
- From: Jerry Krinock <email@hidden>
- Date: Tue, 23 Feb 2010 14:32:29 -0800
On 2010 Feb 23, at 13:17, mmalc Crawford wrote:
> <http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/CoreData/Articles/cdTroubleshooting.html#//apple_ref/doc/uid/TP40002320-SW3>
>
> Custom relationship set mutator methods are not invoked by an array controller
> Problem: You have implemented set mutator methods for a relationship as described in “Custom To-Many Relationship Accessor Methods,” and have bound thecontentSet binding of an NSArrayController instance to a relationship (as illustrated by the Employees array controller in NSPersistentDocument Core Data Tutorial), but the set mutator methods are not invoked when you add objects to and remove objects from the array controller.
>
> Cause: This is a bug.
>
> Remedy: You can work around this by adding self to the contentSet binding's key path. For example, instead of binding to [Department Object Controller].selection.employees, you would bind to [Department Object Controller].selection.self.employees.
Thanks for the pointer to the docs, mmalc. You are concise and accurate as usual. But I like my workaround (implementing setEmployees:) better, because I can put a comment in the code. If I entered a Model Key Path of "selection.self.employees", I'd be worried that someone might look at it one of these days and say "Hmmm. Stupid Jerry. We don't need that '.self' in there, do we!"
Furthermore, I've never been able to find any documentation stating that Cocoa is required to invoke the set mutator method(s). Invoking the setEmployees: method, which both Ken and I have noted *does* happen, is a KVC-compliant technique. So, I'm not sure that it's a bug.
Finally, there are other cases when you're not sure which method is going to be invoked. For example, say that multiple employees are added. Does it invoke addEmployees:, or does it invoke addEmployeesObject: multiple times?
So, I'm sticking to my plan that it is to use KVO whenever possible. But if you need notification *before* the change occurs, you need to override all *five* setters:
- (void)addEmployeesObject:(Employee *)value;
- (void)removeEmployeesObject:(Employee *)value;
- (void)addEmployees:(NSSet *)value;
- (void)removeEmployees:(NSSet *)value;
- (void)setEmployees:(NSSet *)set;
Now I may be overly presumptive in declaring that there are *five* set mutator methods; the four set mutators you get from "Copy Obj-C 2.0 Method Implementations to Clipboard", and the one that we've discovered is actually being used. The documentation:
http://developer.apple.com/Mac/library/documentation/Cocoa/Conceptual/CoreData/Articles/cdAccessorMethods.html#//apple_ref/doc/uid/TP40002154 > Custom To-Many Relationship Accessor Methods
refers rather loosely to "mutator methods (such as...)" but never gives a concise list, although it implies that they are whatever you get in Xcode. That's not exactly what I'd call an "API Contract". I have looked for but have never found an unequivocal statement that "Core Data DEFINES 'N' set mutator methods. They ARE: •, •, •, …."
Rather than fixing the "bug", I think it would be better if Apple would simply document the current behavior, i.e. "When an array controller makes a change, unless it is bound with the '.self.' workaround, it shall invoke -setEmployees:". Then, I'd only need to implement one custom setter instead of five. Well, that is if I trusted myself to not invoke one of the others :) Also, Core Data apps have been shipping for five years now and changing it at this point might break some of them.
_______________________________________________
Cocoa-dev mailing list (email@hidden)
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:
This email sent to email@hidden