带有 nsmutabledictionary 的 UserDefault 无法将类型“__NSSingleEntryDictionaryI”的值转换为 NSMutableDictionary

UserDefault with nsmutabledictionary could not cast value of type '__NSSingleEntryDictionaryI' to NSMutableDictionary

我是 Ios 开发的新手。目前只有一个函数 returning NSMutableDictionary,它存储在 userDefaults 中。但是当我从 userdefault 中检索值时,它的 return NSMutableDictionary 的格式不正确,无法解析 NSMutableDictionary 并且 return 返回错误 "could not cast value of type '__NSSingleEntryDictionaryI' to NSMutableDictionary".

return NSMutableDictionary

的函数
func initializeStructureOfControl () -> NSMutableDictionary {
        var parentSlideControl = NSMutableDictionary()

        var slideControl = NSMutableDictionary()
        slideControl.setValue(NSMutableDictionary(), forKey: UserDefaultKeys.fdtControlKey)
        slideControl.setValue(NSMutableDictionary(), forKey: UserDefaultKeys.pdtControlsData)
        slideControl.setValue(NSMutableDictionary(), forKey: UserDefaultKeys.eeControlsData)
        slideControl.setValue(NSMutableDictionary(), forKey: UserDefaultKeys.fbeControlsData)

        parentSlideControl.setValue(slideControl, forKey: UserDefaultKeys.slideControlKey)

        return parentSlideControl

    }

在用户默认初始化

UserDefaults.standard.setValue( initializeStructureOfControl(), forKey: UserDefaultKeys.slideControlKey)

正在检索值

UserDefaults.standard.object(forKey: UserDefaultKeys.slideControlKey)

保存在 userdefault 中的值:

  ▿ some : 1 element
    ▿ 0 : 2 elements
      ▿ key : slideControlsData
      ▿ value : 4 elements
        ▿ 0 : 2 elements
          - key : fbeControlsData
          - value : 0 elements
        ▿ 1 : 2 elements
          - key : eeControlsData
          - value : 0 elements
        ▿ 2 : 2 elements
          - key : fdtControlsData
          - value : 0 elements
        ▿ 3 : 2 elements
          - key : pdtControlsData
          - value : 0 elements

从 userdefault

得到的值 return
▿ some : 1 element
    ▿ 0 : 2 elements
      ▿ key : slideControlsData
      ▿ value : 4 elements
        ▿ 0 : 2 elements
          - key : fbeControlsData
          - value : 0 elements
        ▿ 1 : 2 elements  
          - key : eeControlsData
          - value : 0 elements {.....}
        ▿ 2 : 2 elements 
          - key : fdtControlsData
          - value : 0 elements {.....}
        ▿ 3 : 2 elements  
          - key : pdtControlsData
          - value : 0 elements {.....}

尽管它在 ios 12 或之前的设备(return 与保存的值相同)中工作,但在 ios 13 和更高版本 return是上面的格式字符串,而不是用户默认保存的格式字符串。

错误

could not cast value of type '__NSSingleEntryDictionaryI' to NSMutableDictionary

发生是因为 object(forKey returns 一个 im 可变对象。要获得可变字典,您必须创建一个新字典,例如

var slideControl = NSMutableDictionary(dictionary: (UserDefaults.standard.object(forKey: UserDefaultKeys.slideControlKey) as! NSDictionary))

但是 Swift 强烈建议不要使用所有 NS(Mutable)... 集合类型。这是原生版本

func initializeStructureOfControl () -> [String:Any] {
    let slideControl = [UserDefaultKeys.fdtControlKey : [String:Any](),
                        UserDefaultKeys.pdtControlsData : [String:Any](),
                        UserDefaultKeys.eeControlsData : [String:Any](),
                        UserDefaultKeys.fbeControlsData : [String:Any]()]
    return [UserDefaultKeys.slideControlKey : slideControl]
}

保存到UserDefaults

UserDefaults.standard.set(initializeStructureOfControl(), forKey: UserDefaultKeys.slideControlKey)

并阅读它

var slideControl = UserDefaults.standard.dictionary(forKey: UserDefaultKeys.slideControlKey)

字典是可变的,因为 variable。但是请考虑 Swift 字典是值类型。您必须就地修改它。更有效的解决方案可能是自定义结构而不是字典和 Codable 协议将对象保存在 UserDefaults.