斯威夫特3:保存数组到UserDefaults错误 - 对象的计数从钥匙
我的应用程序崩溃计数不同,出现错误:斯威夫特3:保存数组到UserDefaults错误 - 对象的计数从钥匙
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSDictionary initWithObjects:forKeys:]: count of objects (0) differs from count of keys (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
字符串。
但我想知道现在的问题可能在哪里。
强行拆包的问题。
NSKeyedUnarchiver.unarchiveObject(with: decoded) as! [Int: AppAnnotation]
使用
NSKeyedUnarchiver.unarchiveObject(with: decoded) as? [Int: AppAnnotation]
退房的方法定义:
open class func unarchiveObject(with data: Data) -> Any?
它返回可选值。
为什么要解决这个问题?它只会避免应用程序崩溃。 –
更改为?没有帮助。同样的错误。这可能是我构造数组的方式:[Int:AppAnnotation]?如果我只重做[AppAnnotation]会怎么样? – Vad
除此之外,其他一切看起来不错。您可以卸载应用程序并重新安装。以前的持久数据可能存在问题。 –
你为什么使用'encodeCInt'?应该是'coder.encode(placeId !, forKey:“placeId”)' –
顺便说一句,为什么你不声明你的AppAnnotation类属性为常量? –
谢谢,我注意到整数编码。但为什么类的属性应该是常量? – Vad