• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Bug in NSArrayController? (immutable instead of mutable dictionaries)
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Bug in NSArrayController? (immutable instead of mutable dictionaries)


  • Subject: Re: Bug in NSArrayController? (immutable instead of mutable dictionaries)
  • From: Uli Zappe <email@hidden>
  • Date: Sat, 23 Oct 2004 02:03:58 +0200

Am 22.10.2004 um 22:54 schrieb Scott Anguish:
On Oct 22, 2004, at 9:22 AM, Uli Zappe wrote:
2. add a respective example to "Binding Your Preferences in Cocoa", which should also point out that it is crucial for this to work at all that you *must* check the "Handles Content as Compound Value" option in the NSArrayController's Bindings Info - something I never would have guessed from the description of this option in the docs

3. provide a factory value transformer that transforms immutable arrays of immutable objects to mutable arrays of mutable objects (yes, that's not hard to do yourself, but it shouldn't be necessary to do again and again given that this is a standard situation - actually, the very reason that such a transformer does not exist in Cocoa made me believe for quite some hours that this just can't be necessary for my implementation to work since it's such a standard task I'm implementing.)

Yes. However, this isn't anywhere near as straight-forward as it seems.

Well, it didn't seem straight-forward to me ;-) , but now that I got it working I didn't encounter any malfunctioning so far in my tests.

Nor does it really solve the problem.

Depends on what you think the problem is. You are much deeper into Bindings than I am, but right now, I cannot see what isn't solved the way I do it.

For handling compound preferences values like this, you're much better off isolating that editing in it's own NSArrayController that uses an intermediate mutable collection. That is, when you enter that 'editing state', get the entire array from NSUserDefaultsController, make a deep mutable copy, and use that with the new NSArrayController. when you leave that editing state (say, switch to another prefs pane) you then set the user defaults with that array.

Hm, it's hard for me to see the crucial difference between the above and what's happening in my implementation.

Let's say I check a checkbox in my GUI that's bound to my NSArrayController. As far as I have understood it, the following is happening:

1. Via KVC, the value of the respective key in the NSMutableDicitonary that is currently the selected one in its content array of NSArrayController is modified.

2. Via KVC, NSArrayController modifies the content of NSUserDefaultsController (which it is bound to). Obviously because of the "Handles Content as Compound Value" setting, the complete content array is sent to NSUserDefaultsController via my custom ImmutableToMutableArrayOfObjectsTransformer. ImmutableToMutableArrayOfObjectsTransformer's -reverseTransformedValue:(id)value method simply returns value, thus the array arrives unmodified at NSUserDefaultsController.

3. In turn, NSUserDefaultsController immediately notifies NSArrayController via KVO that the user defaults have changed. (I have a hard time understanding why this is necessary/unavoidable - I mean, why notify the originator of a change of this very change? The answer is probably that, as you said below, KVC is a one-way operation and NSUserDefaultsController does not know that it was NSArrayController that sent the modification to it.) NSArrayController requests the array and an immutable version of the complete array is sent to it. ImmutableToMutableArrayOfObjectsTransformer makes a deep mutable copy of that array that arrives at NSArrayController and replaces the original content array which with it is identical.

The result of these 3 steps:
a) the new checkbox state is stored in NSArrayController's selected mutable dictionary
b) the new checkbox state is stored in the user preferences

Now, where in the above 3 steps do you think a problem remains? I cannot see it. (Maybe I should add that all the preference values I deal with do not influence the GUI, i.e. no control views in my app are observers of my user defaults. The user default settings are just relevant for my model objects that query NSUserDefaults if they need to know a specific value.)

I was sceptical at the beginning if it is possible at all to bind several controllers together, but Apple's "What Are Cocoa Bindings?" clearly says it is, and I can't see how my implementation differs much from the example in figure 13 of that document.

Editing arrays directly from NSUserDefaultsController has all sorts of issues. If you're saving immediately, you have issues with null values getting in there,

I don't understand that, nor have I experienced it in my test (appliesImmediately, which I think you refer to, is YES in my NSUserDefaultsController). Where should null values come from?

Also, why do you say I edit my array "directly from NSUserDefaultsController"? From my understanding, that's exactly what I don't do. I edit the array in NSArrayController, which *after the change* propagates this change to NSUserDefaultsController via KVC.

if you provide temporary values to avoid that you have data that may not be appropriate being KVO'd throughout the application.

Whatever this means exactly, it probably doesn't apply to my app, because as I said, I have not control views as observers in my app (i.e. the only two observers are NSArrayController and NSUserDefaultsController).

The value transformer idea is a good one, but doesn't work very well from my experience.

Hm, so far it just works for me. What could be problematic?

you have to use Handles as Compound Value,

I have to admit I still have no idea what this option really means and why it is needed (I just found I have to check it for the whole implementation to work).

which means that you have selection issues that come up.

What issues could that possibly be? That after a change in user defaults another dictionary in NSArrayController's content array is selected than before? I couldn't test that thoroughly so far.

The NSUserDefaultsController doesn't know that the NSArrayController that it is sending data back to (via KVO) expects mutability. There isn't a mechanism for that, KVO is a one way message. So, while it's true that it appears that it is two way, they are in fact to entirely separate processes. KVC to set, KVO returns the new value.

Yep, I know, but I still think it's a shame this can't be handled more intelligently.

Honestly, I'm surprised to see how complicated Bindings can become as soon as you have something a bit more advanced in its structure. As I said before, I think handling user preferences are a prime example for the usefulness of Bindings, and still, if they become a little bit more advanced than the very basic case that is dealt with in "Binding Your Preferences in Cocoa", it becomes so problematic immediately. Which is why I think that "Binding Your Preferences in Cocoa" really should be enhanced by additional examples and canonic implementations for cases like the one above.

Bye
Uli
________________________________________________________

Uli Zappe, Solmsstraße 5, D-65189 Wiesbaden, Germany
http://www.ritual.org
Fon: +49-700-ULIZAPPE
Fax: +49-700-ZAPPEFAX
________________________________________________________

_______________________________________________
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
  • Follow-Ups:
    • Re: Bug in NSArrayController? (immutable instead of mutable dictionaries)
      • From: Scott Anguish <email@hidden>
References: 
 >Bug in NSArrayController? (immutable instead of mutable dictionaries) (From: Uli Zappe <email@hidden>)
 >Re: Bug in NSArrayController? (immutable instead of mutable dictionaries) (From: Brent Gulanowski <email@hidden>)
 >Re: Bug in NSArrayController? (immutable instead of mutable dictionaries) (From: Uli Zappe <email@hidden>)
 >Re: Bug in NSArrayController? (immutable instead of mutable dictionaries) (From: Uli Zappe <email@hidden>)
 >Re: Bug in NSArrayController? (immutable instead of mutable dictionaries) (From: Uli Zappe <email@hidden>)
 >Re: Bug in NSArrayController? (immutable instead of mutable dictionaries) (From: "M. Uli Kusterer" <email@hidden>)
 >Re: Bug in NSArrayController? (immutable instead of mutable dictionaries) (From: Uli Zappe <email@hidden>)
 >Re: Bug in NSArrayController? (immutable instead of mutable dictionaries) (From: "M. Uli Kusterer" <email@hidden>)
 >Re: Bug in NSArrayController? (immutable instead of mutable dictionaries) (From: Uli Zappe <email@hidden>)
 >Re: Bug in NSArrayController? (immutable instead of mutable dictionaries) (From: Scott Anguish <email@hidden>)
 >Re: Bug in NSArrayController? (immutable instead of mutable dictionaries) (From: Uli Zappe <email@hidden>)
 >Re: Bug in NSArrayController? (immutable instead of mutable dictionaries) (From: Scott Anguish <email@hidden>)

  • Prev by Date: Re: Menu in iTunes
  • Next by Date: How to disable/gray an NSTextfield (used as static text)
  • Previous by thread: Re: Bug in NSArrayController? (immutable instead of mutable dictionaries)
  • Next by thread: Re: Bug in NSArrayController? (immutable instead of mutable dictionaries)
  • Index(es):
    • Date
    • Thread