On Oct 10, 2010, at 21:52, Rick Mann wrote:

> @dynamic shadowFrame;
> 
> "frame" is a transient Core Data property of Undefined Type, but it's an 
> NSRect in the class file. Its implementation:
> 
> - (NSRect)
> frame
> {
>       [self willAccessValueForKey:@"frame"];
>       NSString* v = self.shadowFrame;
>       [self didAccessValueForKey:@"frame"];
>       NSRect nsR = NSRectFromString(v);
>       return nsR;
> }

The Core Data programming guide is a bit hard to follow on this subject 
(because it talks about the difficult cases and not the easy cases), but I 
*think* this is an unnecessary approach. Just don't put "frame" in the Core 
Data model at all, and let it be a regular property. The implementation is the 
same as you've got, except that you don't need the 
willAccess/didAccess/wiilChange/didChange calls. OTOH, I *think* what you did 
should work fine. I'm pretty sure this is nothing to do with your problem.

On Oct 10, 2010, at 21:52, Rick Mann wrote:

>       VisualizationPlugIn* vp = ...;
>       NSView* view = vp.displayViewController.view; 
>       [vp bind: @"frame" toObject: view withKeyPath: @"frame" options: nil];
> 
> I may not really fully understand bindings, in the sense that I don't know 
> what you mean about NSView not having a "frame" binding. The docs imply that 
> you can only call -bind:... on a binding that you've called 
> -exposeBinding:... on, but someone at Apple told me that you only need to 
> call -exposeBinding:... for IB's sake.


It's more complicated than that. 'exposeBinding...' is necessary only for IB's 
sake, so it's basically irrelevant to this discussion.

However, a binding -- a real, honest-to-goodness Cocoa binding -- needs support 
code in the class that defines the binding. This support code essentially makes 
sure that the bound object are updated in both directions. For *one* of the 
directions (from the bound object to the bound-to object), the standard 
implementation of 'bind:toObject:withKeyPath:options:' in NSObject is normally 
perfectly adequate. The other direction is custom code in the class providing 
the binding.

So, when I said NSView doesn't have a "frame" binding, I meant it doesn't have 
this custom code for a binding named "frame". (It does have the code for a 
binding named "toolTip", for example.)

Under these circumstances, when you call [object1 bind:@"xyz" toObject: object2 
withKeyPath:@"abc" options:...], all you get is object1's KVC-compliant 
property "xyz" following object2's "abc" property, but not vice versa. In that 
sense, this is not about bindings at all -- 'bind...' serves merely as a 
convenient way to set up a uni-directional KVO observance.

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.

If this sounds confusing, it is. The term "binding" is essentially ambiguous is 
very non-trivial way. That's why I strongly object to using 'bind...' for mere 
KVO observance -- it obscures the real operation of the bindings mechanism.

In summary, you've:

1. "bound" in the wrong direction -- you should have attempted to bind from the 
view to the data model (plugin)

2. failed to establish a "frame" binding because none of the classes involve 
has a "frame" binding (just a "frame" property, which is insufficient for your 
purposes)

3. set up a one-way KVO observance that provides precisely half the 
functionality you want

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.

Or something like that.




_______________________________________________

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