应用启动时来自NSUserDefaults的价值不一致

时间:2016-07-06 16:50:48

标签: ios swift nsuserdefaults

在iOS模拟器下,我无法在应用启动时从NSUserDefault获取一致的值。我已经在应用程序的上一次运行中设置了值(我在那里放了一些打印件以确保没有意外更改),所以我不认为我调用synchronize()的方式有问题。读取也发生在主线程上,并在我设置了默认值之后。几秒钟后,如果我重新尝试从NSUserDefaults获取,我得到正确的值(我在那里放了一个计时器来验证值是否得到纠正,并且在启动后似乎保持不变)。

该值表示用户存储数据的位置(在iCloud上或仅在本地设备上),并由用户默认值中的整数表示。这是表示值的枚举:

class MovingDocument: UIDocument {
    enum StorageSettingsState: Int {
        case NoChoice = 0
        case Local = 1
        case ICloud = 2
    }
}

以下是用于访问NSUserDefaults的类的摘录:

class Settings {
    static let global = Settings()

    private enum LocalStoreKeys : String {
        case IsHorizontal = "IsHorizontal"
        case ItemInPortrait = "ItemInPortrait"
        case RotateTitle = "RotateTitle"
        case StorageLocation = "StorageLocation"
    }

    // Other computed variables here for the other settings.

    // Computed variable for the storage setting.
    var storageLocation: MovingDocument.StorageSettingsState {
        get {
            print("Storage state fetch: \(NSUserDefaults.standardUserDefaults().integerForKey(LocalStoreKeys.StorageLocation.rawValue))")
            return MovingDocument.StorageSettingsState(rawValue: NSUserDefaults.standardUserDefaults().integerForKey(LocalStoreKeys.StorageLocation.rawValue)) ?? .NoChoice
        }
        set {
            print("Setting storage location to \(newValue) (\(newValue.rawValue))")
            NSUserDefaults.standardUserDefaults().setInteger(newValue.rawValue, forKey: LocalStoreKeys.StorageLocation.rawValue)
            synchronize()
            CollectionDocument.settingsChanged()
        }
    }

    func prepDefaultValues() {
        NSUserDefaults.standardUserDefaults().registerDefaults([
            LocalStoreKeys.IsHorizontal.rawValue: true,
            LocalStoreKeys.ItemInPortrait.rawValue: true,
            LocalStoreKeys.RotateTitle.rawValue: true,
            LocalStoreKeys.StorageLocation.rawValue: MovingDocument.StorageSettingsState.NoChoice.rawValue
            ])
    }

    func synchronize() {
        NSUserDefaults.standardUserDefaults().synchronize()
    }
}

我应该阅读的值(以及我在启动后似乎总是得到的值)是值'1'或.Local。我有时得到的值是'0'或.NoChoice(恰好是默认值)。因此,它似乎在应用程序启动之后的某个时间点使用默认值。

为了完整起见,这里是相关的应用代理代码:

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    // Override point for customization after application launch.

    Settings.global.prepDefaultValues()  // Must be called before doing CollectionDocument.start() because we need the default value for storage location.
    CollectionDocument.start()
    self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
    browserController = ViewController()
    navController = UINavigationController(rootViewController: browserController!)
    navController!.navigationBar.translucent = false
    self.window!.rootViewController = navController
    self.window!.makeKeyAndVisible()
    checkStorageLocation()
    return true
}

在CollectionDocument.start()中调用getter(CollectionDocument是MovingDocument的子类,其中定义了位置枚举)。 checkStorageLocation()最后的调用是我对存储位置值的定期调试检查(它通过dispatch_after()调用自身。)

作为旁注,我还尝试将应用程序中的大部分代码(didFinishLaunchingWithOptions ...)放入dispatch_async调用(在主线程上)以查看是否有所不同(只是调用设置默认值和return语句立即完成,其余的调用被放入异步调用块),它仍然得到错误的值(有时)。我想我可以尝试使用dispatch_after(并等待一两秒钟),但是在完成之前我无法真正启动应用程序(因为在我知道它的位置之前我无法从文档中读取用户数据)只有这个问题的加载屏幕似乎很荒谬。

关于可能出错的任何想法?我不知道NSUserDefaults的任何限制,只要你被允许阅读它...

1 个答案:

答案 0 :(得分:1)

重新启动我的mac修复了问题(不管它是什么)。 iOS 10, NSUserDefaults Does Not Work有一个类似的问题和相同的解决方案(虽然情况完全不同,因为我既没有尝试Xcode 8也没有尝试iOS 10)。