Re: Elementary NSUserDefaults Question
Re: Elementary NSUserDefaults Question
- Subject: Re: Elementary NSUserDefaults Question
- From: Charles Jenkins <email@hidden>
- Date: Wed, 07 Dec 2016 11:20:50 -0500
That makes sense. Thanks, Ken!
On Wed, Dec 7, 2016 at 11:00 AM, Ken Thomases <email@hidden> wrote:
> On Dec 7, 2016, at 9:25 AM, Charles Jenkins <email@hidden> wrote:
> >
> > I may be misusing NSUserDefaults. I want to store the name of a
> background
> > music file, which may be nil if the user doesn’t want to hear anything.
> For
> > the time being, I have only two settings for my variable
> > “currentBackgroundMusicFileName”: either a file that I distribute with
> the
> > app, or nil.
> >
> > When the app starts up, we call NSUserDefaults.standard.register( [
> “bgm” :
> > <myfilename> ) to default to the real file name, so the user will hear
> > music on first run. Then I call NSUserDefaults.standard.object( forKey:
> > “bgm” ) as? String to read the current setting.
> >
> > When I run the app, I go into my settings and select “None” as the
> > background music file I want to hear, and the variable gets changed and
> we
> > call NSUserDefaults.standard.set( nil, forKey: “bgm” ). The music is
> > silenced.
> >
> > But when I kill the app and start again, the music comes back. Is it it a
> > mistake to try using nil as an object value? Perhaps object( forKey: ) is
> > meant to return the registered default value again instead of the nil
> when
> > I reload the app, making it impossible for me to use nil as a valid
> value?
>
> Sort of.
>
> The user defaults system organizes the defaults into a stack of
> "domains". For any given key, it consults the domains in order. If one
> domain doesn't have a value for the key, it continues on to the next
> domain. Like with a dictionary, nil is not a value, it's the absence of a
> value.
>
> For purposes of this discussion, there are two relevant domains, the
> application domain and the registration domain, consulted in that order.
> The registration domain is the combination of whatever was passed to the
> register() method. It is a volatile domain that's not persisted. It's
> recreated from scratch for each run of the app by your calls to register().
>
> The app domain is where settings are saved for your app. It's a
> persistent domain. The various set(_:forKey:) methods modify this domain.
> Most of them add or modify a value for the key, but set(nil,
> forKey:"someKey") is a special case and removes the key-value pair for the
> given key.
>
> So, your attempt to set nil for a key only ever removes it from the app
> domain (where it never was in the first place), leaving the user defaults
> system to proceed to the next domain, the registration domain, to satisfy
> any future lookups.
>
> You should instead use a boolean key to control whether background music
> plays. If you really intend to allow the user to change which file to play
> from, you could continue to have a key for the file name, but it would be
> subordinate to the boolean as to whether anything should play at all.
>
> Regards,
> Ken
>
>
--
Charles
_______________________________________________
Cocoa-dev mailing list (email@hidden)
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:
This email sent to email@hidden