Swift 3:将数组保存到UserDefaults错误 - 对象计数与键计数不同

时间:2017-05-18 13:35:42

标签: ios arrays swift swift3 nsuserdefaults

我的应用程序因错误而崩溃:

  

由于未捕获的异常'NSInvalidArgumentException'而终止应用程序,原因:'*** - [NSDictionary initWithObjects:forKeys:]:对象计数(0)与键计数不同(1)

以下是我保存var favoriteAppAnnotations = [Int: AppAnnotation]()的方式:

let userDefaults = UserDefaults.standard
let favoritesData: Data = NSKeyedArchiver.archivedData(withRootObject: self.favoriteAppAnnotations)
userDefaults.set(favoritesData, forKey: "FAVORITES")
userDefaults.synchronize()

以下是我加载它的方式:

self.favoriteAppAnnotations = [:]
let userDefaults = UserDefaults.standard
if let decoded = userDefaults.object(forKey: "FAVORITES") as? Data {
   let favoritesArray = NSKeyedUnarchiver.unarchiveObject(with: decoded) as! [Int: AppAnnotation] // THIS IS WHERE THE CRASH IS
   if favoritesArray.isEmpty == false {
       self.favoriteAppAnnotations = favoritesArray
   }
}

AppAnnotation符合这样的NSCoding

    class AppAnnotation: ParentAppAnnotation, NSCoding // Note: ParentAppAnnotation is NSObject but doe snot conform to NSCoding
    {
        open var placeId: Int?
        open var placeName: String?
        open var placeDescription: String?
        override init() {
            super.init()
        }
        init(placeId: Int, placeName: String, placeDescription: String) {
            self.placeId = placeId
            self.placeName = placeName
            self.placeDescription = placeDescription
        }
        required convenience init?(coder decoder: NSCoder) {
            guard let placeName = decoder.decodeObject(forKey: "placeName") as? String,
                  let placeDescription = decoder.decodeObject(forKey: "placeDescription") as? String
                  else { return nil }
            self.init(placeId: decoder.decodeInteger(forKey: "placeId"),
                    placeName: placeName,
                    placeDescription: placeDescription)

        }
        func encode(with coder: NSCoder) {
            coder.encodeCInt(Int32(self.placeId!), forKey: "placeId")
            coder.encode(self.placeName, forKey: "placeName")
            coder.encode(self.placeDescription, forKey: "placeDescription")
        }
    }

我放弃了问题所在。考虑保存数组的其他方法......例如转换为JSON字符串 但我想了解目前的问题所在。

1 个答案:

答案 0 :(得分:0)

强行展开的问题。

NSKeyedUnarchiver.unarchiveObject(with: decoded) as! [Int: AppAnnotation]

使用

NSKeyedUnarchiver.unarchiveObject(with: decoded) as? [Int: AppAnnotation]

查看方法定义:

open class func unarchiveObject(with data: Data) -> Any?

返回可选值。