我正在使用Xcode 10.2.1,iOS 12.1 +,Swift 5
下面的函数应该读取一个归档值并返回它。 您可以看到以前的有效代码(unarchiveObject),直到被淘汰为止。
只要'data'的返回值不是nil,代码就可以工作-这意味着以前已经保存了一个值。 但是,在新安装的应用程序中,由于先前未保存该值,因此崩溃。
致命错误:解开可选值时意外发现nil
由于我不想预加载值,因此编写此函数以使其不会崩溃的正确方法是什么?
(似乎iOS 12+也不推荐使用NSKeyedUnarchiver.unarchiveTopLevelObjectWithData。什么是正确的替代方法?)
func color(forKey defaultName: String) -> UIColor? {
var color: UIColor?
// Working code prior to Swift 5 and iOS 12
// if let colorData = data(forKey: defaultName) {
// color = NSKeyedUnarchiver.unarchiveObject(with: colorData) as? UIColor
// }
// Works unless NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data(forKey: defaultName)!) returns nil
do {
if let colorData = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data(forKey: defaultName)!) as? UIColor {
color = colorData
}
} catch {
//print("Couldn't read file.")
}
return color
}
答案 0 :(得分:1)
在这种情况下,首先将unarchiveObject(with:)
替换为unarchivedObject(ofClass:from:)
。
所有第二个对象都执行相同的可选绑定,例如在Swift 5和iOS 12之前的工作代码中:
func color(forKey defaultName: String) -> UIColor? {
guard let colorData = data(forKey: defaultName) else { return nil }
return try? NSKeyedUnarchiver.unarchivedObject(ofClass: UIColor.self, from: colorData)
}