如何在Swift中处理与NSCoding相关的错误?
使用init?(coder:)它初始化对象时,如果数据无效,则可能无法初始化.我想抓住这些错误并妥善处理它们.为什么init?(coder:)在Swift中没有定义为抛出函数?
NSCoding 将其定义为可选:
init?(coder aDecoder: NSCoder)
Run Code Online (Sandbox Code Playgroud)
因此,检测错误肯定是可能的.
90%的"为什么Swift ......?" 问题可以用"因为可可"来回答.Cocoa没有定义initWithCoder:为返回错误,因此它不会转换为throwsSwift.没有办法将它干净地连接到现有代码.(NSCoding回到NeXTSTEP.我们已经构建了很多软件而没有返回NSError那里.并不意味着它有时可能不太好,但"无法初始化"传统上已经足够了.)
检查nil.这意味着失败了.这就是提供的所有信息.
我从来没有在实践中过分深入地检查整个对象图是否正确.如果不是,那么你很可能无论如何NSKeyedUnarchiver都会得到其他错误,并且记住如果它无法解码会引发一个ObjC异常(!!!).除非你把它包装在一个ObjC中@catch,否则无论如何你都会崩溃.(是的,这很疯狂,但仍然是真的.)
但是,如果我想要非常小心并确保我期望存档中的内容真的存档(即使它们是nil),我可能会这样做(未经测试;它编译但我还没确定真的行):
import Foundation
enum DecodeError: ErrorType {
case MissingProperty(String)
case MalformedProperty(String)
}
extension NSCoder {
func encodeOptionalObject(obj: AnyObject?, forKey key: String) {
let data = obj.map{ NSKeyedArchiver.archivedDataWithRootObject($0) } ?? NSData()
self.encodeObject(data, forKey: key)
}
func decodeRequiredOptionalObjectForKey(key: String) throws -> AnyObject? {
guard let any = self.decodeObjectForKey(key) else {
throw DecodeError.MissingProperty(key)
}
guard let data = any as? NSData else {
throw DecodeError.MalformedProperty(key)
}
if data.length == 0 {
return nil // Found nil
}
// But remember, this will raise an ObjC exception if it's malformed data!
guard let prop = NSKeyedUnarchiver.unarchiveObjectWithData(data) else {
throw DecodeError.MalformedProperty(key)
}
return prop
}
}
class MyClass: NSObject, NSCoding {
static let propertyKey = "property"
let property: String?
init(property: String?) {
self.property = property
}
required init?(coder aDecoder: NSCoder) {
do {
property = try aDecoder.decodeRequiredOptionalObjectForKey(MyClass.propertyKey) as? String
} catch {
// do something with error if you want
property = nil
super.init()
return nil
}
super.init()
}
func encodeWithCoder(aCoder: NSCoder) {
aCoder.encodeOptionalObject(property, forKey: MyClass.propertyKey)
}
}
Run Code Online (Sandbox Code Playgroud)
正如我所说的,我从来没有在Cocoa程序中真正做到这一点.如果存档中的任何内容确实已损坏,您几乎肯定会结束提出ObjC异常,因此所有这些错误检查可能都是过度杀伤.但它确实让你区分"无"和"不存档".我只是将属性单独编码为a NSData然后编码NSData.如果是的话nil,我编码为空NSData.
| 归档时间: |
|
| 查看次数: |
821 次 |
| 最近记录: |