Re: Why aren't my bindings firing?
Re: Why aren't my bindings firing?
- Subject: Re: Why aren't my bindings firing?
- From: Ken Thomases <email@hidden>
- Date: Sat, 28 Jun 2008 04:55:29 -0500
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 (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