NSUserDefaults in iOS Playground

2019-02-16 22:56发布

问题:

There seems to be a strange issue with iOS Playgrounds where NSUserDefaults always returnsnil instead of the actual value.

In an iOS Playground the last line wrongly returns nil.

import UIKit

let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject("This is a test", forKey: "name")
let readString = defaults.objectForKey("name")

In an OSX Playground the last line correctly returns "This is a test".

import Cocoa

let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject("This is a test", forKey: "name")
let readString = defaults.objectForKey("name")

Any idea why this is? Bug?

回答1:

That's not really a bug..... NSUserDefaults is tied to the iOS sandbox environment. Playgrounds doesn't run in this environment. Hence why you won't be able to write files to disk. If you run this code in the application when running via the simulator or device, you'll have access to the sandbox environment and NSUserDefaults will return a proper reference. I do see though that I get a proper reference in playgrounds and can set and get values, so there has to be something else going on here. I just wouldn't rely on this being the way to test this type of functionality due to the nature.

Notice what happens when I synchronize the store.

The value becomes nil due to the fact that there's nothing to persist against.



回答2:

For what it’s worth, the following code works fine in iOS Playground version 1.6.1 (Swift 4):

import Foundation

let defaults = UserDefaults.standard
defaults.set("This is a test", forKey: "name")
let readString = defaults.string(forKey: "name")
print(readString!)

prints:

This is a test


回答3:

The code works correctly in Xcode 6.4 but fails in Xcode 7.0 beta (7A120f).

  1. Betas are known to have bugs.
  2. File a bug report: http://bugreport.apple.com


回答4:

In Xcode 9.2 for iOS it's currently even working that the UserDefaults are saved between reruns of the playground. That was at first irritating me, because I expected that after each stop the UserDefaults would be cleaned, like they were obviously before. So, a warning: UserDefaults are now persisted between reruns, better keep that in mind when searching for bugs, there may be side effects!