Re: NSDictionary and binding
Re: NSDictionary and binding
- Subject: Re: NSDictionary and binding
- From: Greg Hurrell <email@hidden>
- Date: Sat, 27 Nov 2004 00:58:54 +0100
About a month ago I wrote in with a question on Cocoa Bindings, which
mmalcolm Crawford kindly answered. At the time I said I would "study it
some more and reply once I've got it all figured out". Here we are a
month later, and after putting it aside for a while and going off to
work on other things, I've come back to it and finally got the thing
working.
I just wanted to post to the list a big thank you to mmalcolm, not only
for his replies to my questions, but also to the effort he has put in
to maintaining his "Cocoa Bindings Examples and Hints" page
(<http://homepage.mac.com/mmalc/CocoaExamples/controllers.html>) and
the way he's always one of the first people to jump in and reply to
Cocoa Bindings questions, no matter how basic they may seem or how many
times they've been posted to the list.
I always wanted to post some comments on how I got things working in
the end, and the misunderstandings I had about Cocoa bindings, because
it might help another novice in the future who's looking for solutions
to the same problems I was.
Background: I'm using NSUserDefaultsController to manage the
relationship between the NSUserDefaults stored on disk (the model), and
the preferences window in my application (the view). Once the basic
idea is mastered, it is very quick to add a huge number of checkboxes,
textfields, radio buttons etc without having to write lots of glue
code.
The problem: I had one tricky object in my preferences window which was
based on a custom subclass of NSView (an NSTextField subclass, to be
precise). This text field displayed a string representation of some
complex data. It was capable of returning an NSDictionary
representation of that complex data for easy storage in the preferences
plist file on disk. The trouble was, I couldn't figure out how to get
this custom subclass to communicate with NSUserDefaultsController and
Cocoa Bindings.
The failed solution: I tried to expose a binding in my custom class
that corresponded to the complex data. I then tried to bind it using
bind:toObject:withKeyPath:options:. The trouble was that this worked
only in one direction (ie. if the user preferences changed, the
controller would inform the view; but if the view changed, it would not
inform the user preferences). I was confused because the other standard
Cocoa classes (for example NSButtons used as checkboxes) automatically
had two-way communication.
The correct solution: Exposing the binding was good, setting up a
binding was good, but what I didn't realise I had to do was implement
bind:toObject:withKeyPath:options: in my custom subclass. I had wrongly
assumed that it would inherit from the superclass's implementation and
everything would just magically work. This was only part true.
Inheriting the superclass's implementation made only one side of the
relationship work magically. To make it work in both ways I had to
provide my own implementation which not only acted when the controller
notified the custom view of changes, but which notified the controller
when the view changed.
mmalcolm was spot on when he told me to look at the Graphics Bindings
example on his page and look at the "Joystick" view class. This class
shows how you override bind:toObject:withKeyPath:options:, and inside
that method call addObserver:forKeyPath:options:context: and keep track
of the controller(s) and keypath(s). It also shows the other methods
you override, like unbind: and
observeValueForKeyPath:ofObject:change:context. And of course it shows
how the changes are communicated back to the controller when the view
changes.
Anyway, if anyone finds themselves in a similar situation, I encourage
them to look at those samples.
Cheers,
Greg
El 28/10/2004, a las 3:25, Greg Hurrell escribió:
El 28/10/2004, a las 2:05, mmalcolm crawford escribió:
It *sounds* like you're expecting things to work backwards from the
way they do.
Probably due to my confusion. I've done a *lot* of reading on this but
can't make much sense of it. It is definitely the hardest Cocoa topic
I've yet come across since I started two years ago. My brain just
doesn't seem to want to assimilate it!
See the "Joystick" view from the Graphics Bindings example at
<http://homepage.mac.com/mmalc/CocoaExamples/controllers.html>.
Thanks. Funny you should say that. I had downloaded it and was looking
at it when your reply came in. I will study it some more and reply
once I've got it all figured out.
It might be appropriate to write a value transformer to convert
to/from a dictionary from/to your custom class.
Just a quick question on NSValueTransformers... Reading this doc here,
"Writing a Custom Value Transformer",
<file:///Developer/ADC Reference Library/documentation/Cocoa/
Conceptual/ValueTransformers/Concepts/CustomTransformer.html>, I note
that it says: "A value transformer subclass must implement the
transformedValueClass class method. This returns the class of the
object that both the transformedValue: and reverseTransformedValue:
methods will return." This is a little confusing for me because it
indicates that I can, for example, transform from an NSNumber to an
NSNumber, or an NSString to an NSString, but not my ComplexObject
class to NSDictionary...
Perhaps I am reading the docs wrong, but from what you say (and you
seem to know a lot about Cocoa Bindings) you can indeed have a
transformer that moves back and forth between two different types of
class... so which class, then, do I return in my
-transformedValueClass method? The NSDictionary class, or the
ComplexObject class? (Or is this once again a case of my brain not
assimilating a new Cocoa concept?)
Cheers,
Greg
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden