Re: Elementary NSUserDefaults Question
Re: Elementary NSUserDefaults Question
- Subject: Re: Elementary NSUserDefaults Question
- From: Quincey Morris <email@hidden>
- Date: Wed, 07 Dec 2016 11:00:22 -0800
- Feedback-id: 167118m:167118agrif8a:167118sR1CE9f7De:SMTPCORP
On Dec 7, 2016, at 08:24 , Charles Jenkins <email@hidden> wrote:
>
> If anyone knows how to play music from the library at a low volume, without
> screwing up the system volume for other apps, e.g. Music.app, I’d love to
> learn it.
You can play audio using any volume you want (without any side effects on the system volume level) via an AVAudioPlayer.
A couple of points about the “nil” thing, given that you’re writing in Swift:
1. Swift always had a conceptual ambiguity between a nil-valued optional meaning the absence of a value and meaning the presence of a value of Optional type (a 2-valued enum with an associated value on the non-optional case). However, the compiler treated type Optional specially, so that it generally did what you want, even if the semantics were sometimes obscure in edge cases.
2. Swift 3 “improved” the situation by regularizing the behavior for the edge cases, but the side effect was that the semantics of "absent value" vs. "present non-value" have drifted apart a tiny bit. That makes optionals slightly less intuitive to use.
For example, in Swift 3, it’s feasible to allow “nil values” in a dictionary. If you have a dictionary whose values are optional strings (say, [String: String?], to be concrete), and you look up a key that has a value, you get a result of type String?, which may or may not be nil. If you look up a key that has no value, you get a result of “nil as String??”, with two levels of optionality.
That’s confusing but not ambiguous. The trouble is that now we have *two* kinds of presence (concrete values) representing *different* kinds of absence. This is a slippery slope, and I regard it as one indigestible defect in Swift 3.
3. Although user defaults uses NSDictionary semantics — setting a nil value deletes the stored value for the key — this is an Obj-C API. In principle, user defaults *could* allow you to store [Obj-C] NULL values. If you’re keeping track, this is a fourth kind of nil (after “absent”, “String?” and “String??”). But this is Swift, so the story doesn’t end there…
4. Also in Swift 3, it’s possible to bridge any value to Obj-C in APIs where the Swift type is “Any” (but where the type was AnyObject or NSObject in Swift 2). In particular, if you bridge an optional to Obj-C via “Any”, you typically end up with an opaque Obj-C instance (non-nil!) that wraps a Swift type specifier around the nil value, permitting a round-trip to and from Obj-C with complete type safety.
5. Or, in some cases, bridging a nil value will turn it into [NSNull null]. I’m a bit hazy on the details because this is still pretty new.
So, the list of possible interpretations of Swift nil has swollen to:
conceptual absence of a value
presence of a SomeType? value
presence of a SomeType?? value
presence of a SomeType?…? value (an indeterminate number of “?”s)
Obj-C NULL (zero pointer with no type information)
Obj-C opaque instance bundling a zero pointer with a Swift type
Obj-C [NSNull null]
I guess this is a bit OT from your original question, but the message to Swift developers is: Don’t try to store nil values unless you’re very, very sure you need to. In your scenario, if you don’t want to store a separate boolean value, it’d probably be simplest just to store an empty string ("") as the file-name value indicating no background music.
_______________________________________________
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