Re: Elementary NSUserDefaults Question
Re: Elementary NSUserDefaults Question
- Subject: Re: Elementary NSUserDefaults Question
- From: Charles Srstka <email@hidden>
- Date: Wed, 07 Dec 2016 18:39:53 -0600
> On Dec 7, 2016, at 1:00 PM, Quincey Morris <email@hidden> wrote:
>
> On Dec 7, 2016, at 08:24 , Charles Jenkins <email@hidden <mailto: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.
With all that said, when I pass nil to UserDefaults’ set(forKey:) method in Swift 3, instead of deleting the entry like I remember it doing in the past, it ends up writing an NSNull instead of deleting the key (well, actually, it encodes an NSNull using NSKeyedEncoder and then stores that as an NSData, but still). I think this is because of SE-0140 (https://github.com/apple/swift-evolution/blob/master/proposals/0140-bridge-optional-to-nsnull.md <https://github.com/apple/swift-evolution/blob/master/proposals/0140-bridge-optional-to-nsnull.md>), since the method on UserDefaults takes an Any?, and Swift now sends NSNulls to Objective-C methods that do. So, if OP upgrades to Swift 3, he may find that it suddenly does what he wants, albeit accidentally. I’m not sure I’d want to rely on this behavior, though.
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