On Jun 28, 2008, at 3:10 AM, Charles Srstka wrote:

On Jun 28, 2008, at 1:57 AM, Ken Thomases wrote:

That depends on how the bar class from your OP (or one of its superclasses) implemented bind:toObject:withKeyPath:options:. That code may not have checked the passed-in binding name, and may have unconditionally added itself as an observer of ivar_controller for the key path "selection.displayName". That would have guaranteed that bar would receive observeValueForKeyPath:ofObject:change:context: messages whenever foo's displayName property was changed in a KVO-conforming manner. (For example, if, in listing 2 of the how-it-works document, the check of the binding name against "angle" were omitted.)

Then, what happens next is up to bar's implementation of observeValueForKeyPath:ofObject:change:context:. If it blindly did [self setTitle:[object valueForKeyPath:keyPath]], then that would explain it. (For example, if, in listing 4, the test of context were omitted.)

The superclass would be NSView, which doesn't declare bind:toObject:withKeyPath:options: in its header file, nor does NSResponder, so it's likely NSObject's implementation, whatever it does. Interestingly, NSObject's header file doesn't declare this as a method either, although NSKeyValueBinding.h declares it as a category on NSObject, which is apparently why the compiler doesn't complain.

Yeah, it surprises me, too, that NSObject has an implementation of bind:toObject:withKeyPath:options:. I had thought that it was just part of an informal protocol -- that is, that it was declared in a category on NSObject, but never implemented except by specific classes which adopted that protocol. However, I did a symbol dump of the AppKit framework and I see that there is, in fact, an implementation. I have no idea what it could be doing.


Also interestingly, the only reference to the bind:toObject:withKeyPath:options: method that comes up in an API search of the documentation is from the NSKeyValueBindingCreation protocol, which states this:

"Establishes a binding between a given property of the receiver and the property of a given object specified by a given key path."

Since this doesn't seem to be actually the case, someone ought to file a report on the documentation about this.

Yeah, and the description of the "binding" parameter of that method also says it's a "key path for a property of the receiver", which contradicts my understanding (as we've been discussing).

So, my curiosity piqued, I did some more reading. The "Bindings" chapter of the Cocoa Fundamentals Guide <http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaFundamentals/CommunicatingWithObjects/chapter_6_section_6.html > also directly contradicts what I've been saying. It unambiguously states that you can bind together any two objects so long as they're KVC/KVO-compliant. Now _I'm_ confused -- and worried that I've been spreading misinformation.

Time to build a test project...

... time passes ...

OK. So, from what I can see, bindings do work with just KVC/KVO, but they are inherently one-way. That is, the following:

[thing1 bind:@"property1" toObject:thing2 withKeyPath:@"property2" options:nil];

means that thing1's property1 should update itself with the value from thing2's property2 whenever thing2's property2 changes. It does not imply that thing2's property2 will be updated if thing1's property1 changes. If you want that, then you should set it up explicitly:

[thing2 bind:@"property2" toObject:thing1 withKeyPath:@"property1" options:nil];

From my brief testing, this does not produce infinitely looping mutual updates.

However, it seems as though a binding name is _not_ a key path as described in the documentation; it's just a key. Trying to use a key path resulted in exceptions.

None of this jibes with bindings as they're used in views. First, there's that reference listing the bindings supported by various classes. As discussed, the list for NSTextField is decidedly shorter than the list of properties for which NSTextField is KVC/KVO- compliant. That's generally true of most views listed in that reference. Second, establishing a binding to a view is two-way, while establishing non-view bindings is one-way.


It's odd that there's no clear, definitive statement about what happens when you bind the properties of two non-view, non-NSController- derived classes together. As I said above, there is a definite statement that you can do it, just not what happens if you do. The fact that bind:toObject:withKeyPath:options: is only documented as part of an informal protocol and not on NSObject itself implies that there's no default implementation, and yet there is.

I'm quite perplexed.


Oh well, thanks for your patience with my questions.

Thank you for your persistence in asking. It's helped me learn, or at least unlearn. ;)

Cheers,
Ken

_______________________________________________

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 [EMAIL PROTECTED]

Reply via email to