无法更新 NSMutableDictionary?

Posted

技术标签:

【中文标题】无法更新 NSMutableDictionary?【英文标题】:Cannot update 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。

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

【问题讨论】:

看看***.com/questions/5790715/… 不用担心。这也让我感到意外。 【参考方案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()

【讨论】:

以上是关于无法更新 NSMutableDictionary?的主要内容,如果未能解决你的问题,请参考以下文章

如何更新 NSMutableDictionary 中的 NSMutableArray 值

Objective-C:无法从 NSUserDefaults 设置 NSMutableDictionary

无法更新 NSUserDefaults 中字典的键值

NSDictionary 可能无法响应 NSMutableDictionary 对象上的 setObject:forKey

无法将“NSMutableDictionary”类型的值转换为预期的参数类型“[String: AnyObject]?”

无法将类型“NSMutableDictionary”的值转换为强制类型“[NSObject: AnyObject]”以用于 google ios Analytics