【发布时间】:2017-05-18 13:35:41
【问题描述】:
我的应用程序因错误而崩溃:
由于未捕获的异常“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 字符串。
但我想了解当前的问题可能出在哪里。
【问题讨论】:
-
你为什么使用
encodeCInt?应该是coder.encode(placeId!, forKey: "placeId") -
顺便说一句,为什么不将 AppAnnotation 类属性声明为常量?
-
谢谢,我注意到整数编码。但是为什么类的属性应该是常量呢?
-
如果你需要改变它,只需创建一个新对象
-
BTW UserDefaults 有一个方法叫
data(forKey:)
标签: ios arrays swift swift3 nsuserdefaults