Re: NSKeyValueObservingOptionNew broken for NSArrayController: best practice workarounds?
Re: NSKeyValueObservingOptionNew broken for NSArrayController: best practice workarounds?
- Subject: Re: NSKeyValueObservingOptionNew broken for NSArrayController: best practice workarounds?
- From: Mailing list subscriptions <email@hidden>
- Date: Sat, 7 Oct 2006 17:11:22 +0200
El 5/10/2006, a las 18:25, Mailing list subscriptions escribió:
I've seen many threads about the change dictionary in
observeValueForKeyPath:ofObject:change:ontext: returning NULL
values when NSKeyValueObservingOptionNew or
NSKeyValueObservingOptionOld is passed to the
addObserver:forKeyPath:options:context: of NSArrayController.
What's the best workaround for this, then?
- subclass NSArrayController and override the KVO methods until I
fix the breakage (not exactly sure how far I'd need to go with that)
- in my observer keep a record of the "last known state" and then
compare it against the new state whenever a notification is
received (ie manually figure out what changed)
- some sort of willChange/didChange trickery (did experiment with
this but didn't cure the problem)
Replying to my own post for the benefit of those searching the
archives; there is a fourth option: totally refactoring your design.
My code initially looked like this:
NSUserDefaults (model) <-> NSUserDefaultsController <->
NSArrayController <-> NSTableView
The objects in NSUserDefaults were NSDictionaries in an array.
Basically, I wanted to observe changes in that array, so from my main
controller I registered as an observer. I chose this design because
it was the "simplest" and required the smallest amount of glue code.
I found that I was able to work around the
NSKeyValueObservingOptionNew bug by restructuring things like this:
NSUserDefaults (model) <-> Custom/main controller <->
NSArrayController <-> NSTableView
So basically I cut NSUserDefaultsController out of the loop and
instead of storing an array of NSDictionaries in NSUserDefaults I now
store an array of custom objects (requiring me to implement the
NSCoding protocol in the custom class and write code using
NSKeyedArchiver and NSKeyedUnarchiver in my main controller to handle
the writing of the array to and from NSUserDefaults). I also had to
write indexed accessor methods as a result of the move.
By writing a custom class for the objects in the array, I no longer
need to worry so much about things in the main controller because the
objects themselves can now handle some of the work that the main
controller would have done. In that sense the Cocoa bug has forced me
to encapsulate things better and the design is now cleaner. On the
down side, I had to write methods in the main controller for adding
objects to/from the array, because some special behaviour was needed
to set up the objects.
Even though Cocoa Bindings is supposed to cut out a lot of glue code,
there's a hell of a lot of glue in there after these changes, but it
seems that the design is basically "correct" and doesn't break any
Cocoa Bindings "best practice" guidelines. Here are some source code
line counts:
- NSIndexSet enumeration support: 201 lines
- Drag and drop support category: 38 lines
- Custom array controller (drag and drop aware): 124 lines
- Custom table view (delete-key support): 97 lines
- Custom model class: 134 lines
- Main controller: 263
- Value transformers: 69 lines
_______________________________________________
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