获取UserDefault字典值时,启用App SandBox会导致崩溃

时间:2018-07-20 16:56:03

标签: swift macos nsuserdefaults

我已经使用调试器进行了测试,并且我感兴趣的Dictionaryvalue都不为零。当我启用应用程序Sandbox时,应用程序崩溃,但是当我禁用它时,一切正常。在启用Sandbox的情况下使用UserDefaults时可以做什么?

发生崩溃的代码:

func getPreferenceSettings(_ aKey: String) -> Bool
{
  var lastPreferenceSetting: Bool!
  if let currentSetting: Dictionary<String, Bool> = UserDefaults.standard.object(forKey: "defaultValues") as? Dictionary<String,Bool>{
    lastPreferenceSetting = currentSetting[aKey]! //crash at this line
  }else{
    //show error to the user
  }
  return lastPreferenceSetting
}

我正在使用Xcode 9.4

2 个答案:

答案 0 :(得分:0)

关键值是nil(我使用的是Release方案而不是Debug,这就是为什么我无法看到它的值并假定它不是nil)的原因。同样在调试器的帮助下,我能够看到密钥从未保存在字典中。奇怪的是,禁用Sandbox时不会发生崩溃。我已经按照以下方式修改了该方法,以便它返回一个可选值,然后调用方使用optional binding检查是否有密钥。

func getPreferenceSettings(_ aKey: String) -> Bool?
{
  var lastPreferenceSetting: Bool?
  if let currentSetting: Dictionary<String, Bool> = UserDefaults.standard.object(forKey: "defaultValues") as? Dictionary<String,Bool>{
    lastPreferenceSetting = currentSetting[aKey]
  }else{
    //show error to the user
  }
  return lastPreferenceSetting
}

编辑

@vadian

  1. 我正在阅读何时正确使用?类型,它通常用于指示缺少值,例如Person的中间名。但是在这种情况下,偏好属性始终存在于项目中,因为它由开发人员进行了硬编码(除非,就像我在忘记将其添加到UserDefaults并在更新字典之前必须先清除它时发生的情况一样)使用新密钥)。如果我理解正确,那么请按照您的书面回答,返回一个Bool?值,然后在调用方方法中检查optional binding是否为nil。不仅应该针对用户端的中间名,还应该针对开发人员方,因为可能会有其他开发人员传递错误的aKey,对吗?

  2. lastPreferenceSetting声明为?也是正确的,因为如果我使用默认值并且if let的计算结果为false,则该函数可能不会返回预期的结果值。

答案 1 :(得分:0)

您必须检查键defaultValuesaKey是否同时存在。由于返回值是非可选的,因此返回false作为默认值。

此代码使用专用方法dictionary(forKey

func getPreferenceSettings(_ aKey: String) -> Bool
{
  if let currentSetting = UserDefaults.standard.dictionary(forKey: "defaultValues"),
     let lastPreferenceSetting = currentSetting[aKey] as? Bool {
        return lastPreferenceSetting
  } else {
      //show error to the user
  }
  return false
}