【问题标题】:Cannot update NSMutableDictionary?无法更新 NSMutableDictionary?
【发布时间】:2016-02-03 20:44:31
【问题描述】:

我不明白为什么我在使用此方法时会出错:

let loginCountKey = "loginCount"
let appReviewParamsKey = "appReviewParams"

func resetLoginCount() {
    let defaults = NSUserDefaults.standardUserDefaults()

    if let reviewParameters = defaults.valueForKey(appReviewParamsKey) as? NSMutableDictionary {
        reviewParameters[loginCountKey] = 1

        defaults.setObject(reviewParameters, forKey: appReviewParamsKey)
        defaults.synchronize()
    }
}

setObject 行给我一个错误:caught "NSInternalInconsistencyException", ... mutating method sent to immutable object"

调试时,reviewParameters 显示为 NSMutableDictionary。我还尝试了 if var 而不是 if let (但它应该是不必要的)并得到了同样的错误。

我还尝试将值设置为 NSNumber(int: 1) 而不是 1。

为什么这会导致给定的错误?

【问题讨论】:

标签: swift nsmutabledictionary


【解决方案1】:

有两个问题:

  • NSUserDefaults 在转换为 Foundation 类型时返回不可变对象
  • 即使返回的值是可变的,您也可以将其分配给一个常量 (let),这使得该对象在 Swift 中是不可变的。

在 Swift 中,推荐的方法是使用原生 Swift 类型和变量 (var),例如

func resetLoginCount() {
  let defaults = NSUserDefaults.standardUserDefaults()

  if var reviewParameters = defaults.objectForKey(appReviewParamsKey) as? [String:AnyObject] {
    reviewParameters[loginCountKey] = 1

    defaults.setObject(reviewParameters, forKey: appReviewParamsKey)
    defaults.synchronize()
  }
}

【讨论】:

    【解决方案2】:

    NSUserDefaults.objectForKey(一般 KVC 方法 valueForKey 必须调用它)在找到该默认键的字典格式数据时返回不可变的 NSDictionary

    使用as?cast,而不是conversion。也就是说,您告诉 Swift 解释您拥有的字典就好像它是 NSMutableDictionary(即使它不是,这就是失败的原因)。如果您想将NSDictionary转换NSMutableDictionary,则需要从前者创建后者的实例(使用mutableCopyinitWithDictionary:)。

    但您甚至不需要在这里使用 Foundation 字典 — NSDictionary 会自动桥接到 Swift 字典,您可以强制转换以解释它 as 正确的键/值类型。您可以使用if var 而不是if let 将可选值绑定为可变值:

    if var reviewParameters = defaults.objectForKey(appReviewParamsKey) as? [String: Int] {
        reviewParameters[loginCountKey] = 1
    
        defaults.setObject(reviewParameters, forKey: appReviewParamsKey)
        defaults.synchronize()
    }
    

    【讨论】:

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