【问题标题】:Swift NSUserDefaults first time nilSwift NSUserDefaults 第一次为零
【发布时间】:2015-07-06 17:46:13
【问题描述】:

您好,我的应用程序在我第一次运行时崩溃了。这是我的代码:

 let State = save.stringForKey("StateSave")
 let City = save.stringForKey("CitySave")
 let Vehicle = save.stringForKey("ModelNumberSave")
 let ExtensionPeriod = save.stringForKey("ExtensionPeriodChoosed")
 let Location = "Location"


 if ExtensionPeriod == nil {
      let name = ""
      var FieldChoosed: Void = save.setObject(name, forKey: "ExtensionPeriodChoosed")
      save.synchronize()

 }

 save.synchronize()
 var DetailNames = ["\(State!)","\(City!)","\(Location)","\(Vehicle!)","\(ExtensionPeriod!)"]

我在这一行收到nil

var DetailNames = ["(State!)","(City!)","(Location)","(Vehicle!)","(ExtensionPeriod!)"]

实际上ExtensionPeriodnil。但我不明白为什么...ExtensionPeriodnil,但是在我编写的代码中,ExtensionPeriod 会像“”,所以它不是nil。请帮帮我。

【问题讨论】:

  • func stringForKey(_ defaultName: String) -> String?

标签: swift nsuserdefaults


【解决方案1】:

stringForKey 在尚未保存值时返回nil

你需要给你的值一个默认值。最简单的方法是使用 ?? 运算符,它将 nil 替换为另一个值:

let State = save.stringForKey("StateSave") ?? "-"

一些一般性建议:您需要停止使用!。通常当某些东西返回nil 时,这是有充分理由的——它可能是nil。当你用! 解包时,你的程序会崩溃(关于原因没有太多有用的信息)。同样,如果您将值与 nil 进行比较,这通常是一个不好的信号。

相反,请查看this list 的一些可选处理技术。

【讨论】:

【解决方案2】:

Airspeed Velocity 有一个很好的解决方案,可以用正确的方式完成你想做的事情,但他并没有真正解释为什么你所做的事情不起作用,所以我将解决这个问题的这方面。

if ExtensionPeriod == nil {
    let name = ""
    var FieldChoosed: Void = save.setObject(name, forKey: "ExtensionPeriodChoosed")
    save.synchronize()
}

该代码块没有设置 ExtensionPeriod,因此 ExtensionPeriod 仍然为零。它所做的只是将 NSUserDefaults 中键“ExtensionPeriodChoosed”的值设置为不再为零。然而,局部变量 ExtensionPeriod 仍然为零。 ExtensionPeriod 不只是神奇地指向存储在 NSUserDefaults 中的变量,因此当您更新 NSUserDefaults 时,它会自动更新该变量。相反,它会在创建变量时复制它。

这里有一些示例代码可以证明这一点:

    NSUserDefaults.standardUserDefaults().setValue("string", forKey: "s")
    NSUserDefaults.standardUserDefaults().synchronize()
    var s = NSUserDefaults.standardUserDefaults().valueForKey("s")
    
    NSUserDefaults.standardUserDefaults().setValue("string2", forKey: "s")
    NSUserDefaults.standardUserDefaults().synchronize()
    var y = NSUserDefaults.standardUserDefaults().valueForKey("s")
    
    println(s)
    println(y)

输出:

“字符串”

“字符串2”

为了使您的代码能够正常工作,如果您要保持其结构相同(尽管您确实不应该),您需要将 ExtensionPeriod 更改为 var,然后在您的 if 块中,同步保存后,您必须将 ExtensionPeriod 重新分配给 save.valueForKey("ExtensionPeriodChoosed")。

【讨论】:

  • 不需要synchronize(),除非您属于 Apple 定义的合适的狭窄类别之一。这不是这些类别之一。
  • @JonShier Fair,我只是让样本尽可能接近 OP 的原始示例。
  • 谢谢你的解释:)
【解决方案3】:

确保应用默认设置的一种方法是使用NSUserDefaultregisterDefaults(_: [NSObject : AnyObject]) 函数。在 Objective-C 中,我经常放入 + (void)initialize 类方法,但覆盖应用程序委托的 init() 应该也可以。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多