用户默认值不随Swift 3一起保存

And*_*ino 12 save nsuserdefaults ios swift

我正在尝试使用UserDefaults持久保存一个布尔值.这是我的代码:

public static var isOffline = UserDefaults.standard.bool(forKey: "isOffline") {
        didSet {
            print("Saving isOffline flag which is now \(isOffline)")
            UserDefaults.standard.set(isOffline, forKey: "isOffline")
            UserDefaults.standard.synchronize()
        }
    }
Run Code Online (Sandbox Code Playgroud)

为什么不起作用?这段代码有什么问题?

编辑:问题是,当我尝试从中检索"isOffline"密钥时,UserDefaults我总是得到一个false.

编辑2:我在行的.onChange方法中设置了isOffline(我使用Eureka作为框架来创建表单).该标志在应用程序的生命周期中保持正确的值,但是当我关闭它时,该值可能会以某种方式被删除.

小智 21

我有同样的问题,问题出在"didSet"块本身.我不知道为什么,但它不适用于userDefaults - 它没有正确地保持它并且在杀死应用程序后所有的更改都消失了.

Synchronize()没有帮助.我发现,这个方法不再需要了,将来会被弃用(这是UserDefaults类中的注释):

-synchronize已弃用,将在以后的版本中使用NS_DEPRECATED宏标记.

通过反复试验,我发现,如果我从主线程中调用它,它可以工作:

public static var isOffline = UserDefaults.standard.bool(forKey: "isOffline") {
        didSet {
            print("Saving isOffline flag which is now \(isOffline)")
            DispatchQueue.main.async {
                    UserDefaults.standard.set(isOffline, forKey: "isOffline")
                }

        }
    }
Run Code Online (Sandbox Code Playgroud)

如果有人可以解释,为什么它在主线程上运行而不是其他,我会很高兴听到它.

  • “在运行时,您使用 UserDefaults 对象从用户的默认值数据库中读取应用程序使用的默认值。UserDefaults 会缓存这些信息,以避免每次需要默认值时都必须打开用户的默认值数据库。当您设置默认值时,它在您的流程中同步更改,并与持久存储和其他流程异步更改。” 这可能是因为缓存的原因,并且在主线程上进行更改可能是默认值被立即写入的原因。 (2认同)

Oma*_*ali 7

尝试改变

UserDefaults.standard.set(isOffline, forKey: "isOffline")
Run Code Online (Sandbox Code Playgroud)

UserDefaults.standard.setValue(isOffline, forKey: "isOffline")
Run Code Online (Sandbox Code Playgroud)

没有发货代码

  • 你知道为什么 set() 函数不起作用吗?因为它在我的设备上看起来有点随机。有时它有效,有时它适用于一些值。有时则不然。奇怪的是。有时我存储这些值,然后加载它们,但什么也没得到。然后我重新启动应用程序,突然一些值又回来了。有了 setValue,这些问题似乎都消失了。但我真的很想知道为什么!:) (4认同)

Ven*_*enk 2

这样做,

public static var isOffline:Bool {
    get {
       return UserDefaults.standard.bool(forKey: "isOffline")
    }
    set(newValue) {
        print("Saving isOffline flag which is now \(isOffline)")
        UserDefaults.standard.set(newValue, forKey: "isOffline")
        UserDefaults.standard.synchronize()
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 您的第一个示例将不起作用,因为您绑定的所谓“newValue”实际上是属性的“旧值”。但这两个例子都没有回答OP的问题“这段代码有什么问题?”。 (2认同)