On Feb 2, 2010, at 1:20 PM, Quincey Morris wrote:

> 1. There are three (3) [III] agents involved in a binding.
> 
> -- Class A (typically some kind of view) defines+implements a binding 
> [behavior] identified by an attribute "x". "Attribute" is not the best choice 
> of terminology, but it's what the documentation uses. It's basically an 
> arbitrary string with a meaning that's internal to A, though sometimes it 
> happens to be a KVC property name too. The attribute may or may not be 
> "exposed" to IB as a "binding name".
> 
> -- Class B (typically a data model object) defines+implements a KVC property 
> "y".
> 
> -- Class C (typically some kind of controller) is responsible for hooking 
> things up. If the binding is set up in IB, C's behavior is somewhere inside 
> the nib-loading code. If the binding is established programmatically, C is an 
> application-defined class.
> 
> 2. An object c of class C establishes a binding [link] from attribute "x" of 
> an object a of class A to property "y" of an object b of class, by sending 
> this message:
> 
>       [a bind: @"x" toObject: b withKeyPath: @"y" options: ...];

This is not usually the case. Object c will usually emit:

        [a bind: @"x" toObject: c withKeyPath: @"z" options: ...];

Where "z" is a property of c or a key path "z.y" as controllers typically 
"control" one model (b). If you write the controller you could certainly bind 
directly as you show, but then you have to unbind/rebind any time your model 
object changes (to a different object), or you have to wait until the model 
object exists before binding. Not a very extensible design.

> Note that A, B and C are *not* necessarily distinct. Often A == C and a == c:
> 
>       [self bind: @"x" toObject: b withKeyPath: @"y" options: ...];
> 
> In terms of establishing a binding [link], that's the whole story. C does not 
> care what the implementation of 'bind:...' is -- that's an implementation 
> detail inside A. All C cares about is that sending this message causes the 
> binding [link] to exist.
> 
> Certainly C knows that 'bind:...' must set up some machinery to make A's 
> binding [behavior] work, but it's a mistake to think that this machinery *is* 
> the binding [behavior]. That's where the discussion usually goes off the 
> rails. The train wreck is made more likely because:
> 
> -- there's no proper terminology to distinguish a binding [link] from a 
> binding [behavior]
> 
> -- NSObject's implementation of 'bind:...' happens to do something that's 
> sort of useful in isolation, if class A doesn't actually define binding "x' 
> but has a KVC property "x"

I don't believe this is true--it is simply the default behavior of NSObject (se 
also below) when "A" has KVC property "x". The one bind call is sufficient for 
the entire binding behavior to function, as long as every key along the bound 
key path is KVO compliant. Nothing additional is required. There is 
documentation about cleaning up bindings, but I think even that is done 
automatically for conforming properties.

> It'd be better for everyone, I think, if NSObject had no implementation of 
> 'bind:...' at all, or if its implementation was moved to a convenience method 
> that didn't mention the word "binding".
> 
> 3. Class A is responsible for providing the binding [behavior]. This consists 
> of three parts:
> 
> -- An implementation of NSKeyValueBindingProtocol. Most significantly, an 
> implementation of the 'bind:...' method.
> 
> -- Detection of changes in the bound-to property ("y" in class B, above), and 
> synchronization of its "x" attribute to such changes.

Yes, except for the "z"/"z.y" clarifications above.

> -- Propagation of changes to its "x" attribute to the bound-to property.
> 
> It can do this any way it wants. Really. An outside agent (class C) can 
> assume *nothing* about the implementation of an arbitrary binding in A, 
> beyond conformance to the protocol. The implementation may or may not use 
> KVO. The implementation may or may not use NSObject's 'bind:...'.

Well, C *can* assume that if it emits a KVO notice of a bound property that it 
has fulfilled its part of the bargain. This is a documented necessity--all 
bound objects along the key path must be KVO compliant. Whether or not "A" does 
anything about it is another matter. "A" could be broken.

> If you follow along with the documentation, part 3 is always custom code. 
> Part 2 is most naturally done with KVO, and set up in the 'bind:...' method. 
> Class A might provide its own implementation of that method, or it might 
> leverage the NSObject implementation.

No, NSObject has a default implementation for part 3. You don't need to code 
anything. You *could*, but you don't have to as long as your follow KVO rules. 
I don't think this is an accident--it is by design. In the same way that an 
accessor is not necessarily an ivar, a binding name is not necessarily a named 
property in any official sense, but that doesn't define its behavior, it simply 
reflects its interface.

> 4. The disputatious part of all this is whether it's valid or safe for class 
> C to send a 'bind: @"x" ...' message to an A object when A does *not* 
> actually provide a binding [behavior] for "x" (such as, when "x" is merely a 
> KVC property of A).
> 
> My answer is that it's not in the API contract, so it's not a good idea. 
> Other people seem determined to do it anyway.

I suppose anything is ultimately disputable, but I would argue that it is 
documented that NSObject implements the binding protocol and I take that to 
mean it fulfills the API contract. Practice also shows this to be true.

Keary Suska
Esoteritech, Inc.
"Demystifying technology for your home or business"

_______________________________________________

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