Re: The problem with bindings
Re: The problem with bindings
- Subject: Re: The problem with bindings
- From: Steve Sims <email@hidden>
- Date: Fri, 30 Jul 2004 15:34:07 -0400
On 29 Jul 2004, at 16:03, Gwynne wrote:
Warning: This email gets a little rant-ish. Read at your own risk.
:-)
I've had bindings crash on me. Create a window in IB. Put a button in
it. Create a subclass of NSObject and instantiate it. Hook it up as
the contentObject of an NSObjectController. Put an window outlet in
the object and hook the window up to it. Bind the button's target to
NSObjectController->selection.window with the performClose: selector,
and bind the first argument to NSObjectController->selection.window
too. Now try running a program (not IB's simulator) that uses this
window. Click the button and crash. Now change the argument binding to
just NSObjectController->selection. No crash. Try hooking a window's
"visible" binding to anything and then running IB's simulator on that
window. Try clicking a button that has target and argument bindings in
IB's simulator and watch IB explode.
OK, I'm too lazy to try this, but I'll take your word for it.
The only crash I've seen that I can think of that might be related to
bindings is with IB. It doesn't like simulating the window of my app,
coming up with a big stack of warnings about my data model, and it will
crash when I attempt to save the nib file after the simulation has
finished. A bit frustrating - I lost a few UI changes from this,
although I rarely use IB's simulator.
Also, I've found myself trying "too" hard to use bindings everywhere.
There are times when the outlet-connection model works better for
things, and there are times when bindings are better. Finding the
happy medium where you make maximum effective use of both is tricky,
especially since there are several things you can't bind in IB even
though it'd make amazing sense to bind them (say, the target/argument
bindings of most button types or any text field). Don't let anyone kid
you that bindings are the solution to end all solutions for user
interface manipulation.
I don't think bindings are intended to be a panacea, and nor do I
believe they've been billed as such. A sensible combination of
bindings and other approaches is clearly the way to go.
Having said that a lot of the time when I've been struggling to see how
to do something with bindings it's because I'm trying to create a UI
that's too complicated. A bit of thought on the subject usually
results in a simpler UI that's less confusing for the user and easier
to bind up.
Something as simple as this doesn't work like you'd expect:
+ (void)initialize
{
[self setKeys:[NSArray arrayWithObject:@"key1"]
triggerChangeNotificationsForDependentKey:@"key2"];
[self setKeys:[NSArray arrayWithObject:@"key2"]
triggerChangeNotificationsForDependentKey:@"key3"];
}
Now [someObject setValue:anyValue forKey:@"key1"]. key2 will be
updated, but no change notification for key3. Also, you can't do this:
Yeah, I ran into this one. I'm not entirely sure that what's happening
right now is "correct", since KVC and KVO should ensure that if key1
changes then key2 should be indicated to have changed, and if key2 is
indicated to have changed then key3 should be indicated to have
changed...
To my way of thinking, and for my purposes, the mechanism offered by
"triggerChangeNotifications..." was around the wrong way. For input
I'm fine with the UI driving the data, but for output I'm more
comfortable with my data driving the UI. So I ended up using KVO's
"addObserver" and the corresponding "observeValueForKeyPath", making
use of the context field to know what has changed. See mmalc's
graphics bindings example at:
http://homepage.mac.com/mmalc/CocoaExamples/controllers.html
for an example of this technique.
[self setKeys:[NSArray arrayWithObject:@"singleKey"]
triggerChangeNotificationsForDependentKeys:[NSArray
arrayWithObjects:...]];
Or in English, you can't easily make multiple keys dependent on a
single key; you have to call [self
setKeys:triggerChangeNotificationsForDependentKey:] with the same
array over and over.
With these examples I can't help but think that manual observer
notification might be a better way to go. See:
http://developer.apple.com/documentation/Cocoa/Conceptual/
KeyValueObserving/Concepts/AutoVsManual.html#//apple_ref/doc/uid/
20001844/BAJEAIEE
Adopting bindings correctly requires a Major change in how you think
of and structure your model, and if you're not careful you can end up
making your code more complicated.
For me the change wasn't all that major... However bindings and more
specifically KVO isn't perfect, and I found that they do have their
limitations.
For example one thing that I wanted to do was react to changes in any
key within a "container" object inside my model. Observing for changes
in "container" don't work - you need to observe for "container.key1",
"container.key2" and "container.key3". This didn't make sense to me,
since if "container.key1" changes then logically "container" has
changed too by my way of thinking. Which reminds me, I should file an
enhancement request on that one.
Steve
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.