On Oct 10, 2010, at 22:31:47, Quincey Morris wrote:

> One way or another, you're going to have to come up with code to handle both 
> directions of frame change: model-to-view  and view-to-model. One approach is 
> to use KVO observance (via [view bind:@'frame" toObject:vp 
> withKeyPath:@"frame" options:0] if you really want to -- note the change of 
> direction) for one direction, and have a controller object (such as a view 
> controller or window controller) observe frame-change notifications from the 
> view and update the model property directly.

I'm still struggling to understand how this stuff works. I mean, given a pair 
of KVO-compliant properties, I don't see why Cocoa can't handle it all for me 
with a single call to -bind:…. But since I want to get this to actually work, 
I'll try to do it their way. Problem is, I just don't get how that's supposed 
to be.

I'm looking at the BindingsJoystick example. It subclasses NSView, and 
implements a -bind:… method for it:

- (void)bind:(NSString *)bindingName
    toObject:(id)observableController
 withKeyPath:(NSString *)keyPath
     options:(NSDictionary *)options
{       
    if ([bindingName isEqualToString:@"angle"])
    {
                // observe the controller for changes -- note, pass binding 
identifier
                // as the context, so we get that back in 
observeValueForKeyPath:...
                // that way we can determine what needs to be updated.
                [observableController addObserver:self
                                                           forKeyPath:keyPath 
                                                                  options:nil
                                                                  
context:AngleObservationContext];
                
                // register what controller and what keypath are 
                // associated with this binding
                [self setObservedObjectForAngle:observableController];
                [self setObservedKeyPathForAngle:keyPath];
                // options
                angleValueTransformerName = [[options 
objectForKey:NSValueTransformerNameBindingOption] copy];
                allowsMultipleSelectionForAngle = NO;
                if ([[options 
objectForKey:NSAllowsEditingMultipleValuesSelectionBindingOption] boolValue])
                {
                        allowsMultipleSelectionForAngle = YES;
                }
    }
    
    if ([bindingName isEqualToString:@"offset"])
    {
                [observableController addObserver:self
                                                           forKeyPath:keyPath 
                                                                  options:nil
                                                                  
context:OffsetObservationContext];
                
                [self setObservedObjectForOffset:observableController];
                [self setObservedKeyPathForOffset:keyPath];
                allowsMultipleSelectionForOffset = NO;
                if ([[options 
objectForKey:NSAllowsEditingMultipleValuesSelectionBindingOption] boolValue])
                {
                        allowsMultipleSelectionForOffset = YES;
                }
    }
        
        [super bind:bindingName
           toObject:observableController
        withKeyPath:keyPath
                options:options];
        
        [self setNeedsDisplay:YES];
}


It then calls -bind:… on the  joystick view like this:

        [joystick bind:@"angle"
                  toObject:arrayController
           withKeyPath:@"selection.angle"
                   options:options];

In the joystick's bind, it explicitly sets up to observe changes in the angle 
on the arrayController's selection. But I don't get why they need to do that. 
Here's why:

Analogously, I was calling -bind:… on my PlugIn model object. According to you

> In your case, you reversed the order of the objects -- you "bound" the 
> plugin's "frame" property to the view's "frame" property. In other words, you 
> told your plugin object to KVO observe the view, and nothing more. That's why 
> moving the view changes the model. But since it's uni-directional, changing 
> the model (e.g. via undo) doesn't change the view.

And I definitely had this behavior; the model noticed changes in the view. In 
other words, sending -bind:… makes the receiver observe the thing. If calling 
-bind:… on the joystick makes it observe the thing, then why does it explicitly 
observe it in its implementation, anyway?

So, I've been preparing to implement -bind:… on my NSViewController subclass, 
rather than subclass NSView. I should be able to do this on either side of 
things, right? But I feel like it's redundant to observe the thing passed to 
you in bind, because I've demonstrated that that happens automatically (when 
you call -bind:…).

What all the examples seem to have in common is an NSObjectController (or 
subclass) fronting for the model object. I don't really have that, and I'm a 
little reluctant to add one (it's yet another object). I have to have an 
NSViewController, because there are potentially complex views associated with 
each PlugIn. I can add an NSObjectController that represents the PlugIn (the 
model object), but I tried this and it didn't work. It also rubs me the wrong 
way that NSObjectController has a notion of a "selection," which really isn't 
appropriate in this situation. I have a model and a view that I want bound to 
each other, and the view will never switch to refer to another model object.

So, I'm still unsure and uncomfortable with how this is supposed to be done.

And in all this, I don't see how bindings fulfills the promise of relieving me 
from writing glue code.

Thanks again for your help so far!

-- 
Rick

_______________________________________________

Cocoa-dev mailing list ([email protected])

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