结构体与 NSCoding
要使用 我找到了一种优雅的方式来将结构体包在 struct Coordinate: JSONInitializable { let latitude: Double let longitude: Double init(latitude: Double,longitude: Double) { self.latitude = latitude self.longitude = longitude } } 这是一个简单的类型,带有两个常量属性。接下来我将创建一个遵循 class EncodableCoordinate: NSObject,NSCoding { var coordinate: Coordinate? init(coordinate: Coordinate?) { self.coordinate = coordinate } required init?(coder decoder: NSCoder) { guard let latitude = decoder.decodeObject(forKey: "latitude") as? Double,let longitude = decoder.decodeObject(forKey: "longitude") as? Double else { return nil } coordinate = Coordinate(latitude: latitude,longitude: longitude) } func encode(with encoder: NSCoder) { encoder.encode(coordinate?.latitude,forKey: "latitude") encoder.encode(coordinate?.longitude,forKey: "longitude") } } 把以上的逻辑放在另一个类型中是合情合理的,这样可以更严格地适用单一职责原则(single responsibility principle)。聪明的读者在阅读上面的类时,会发现 然而由于 从现在开始,我们可以创建 let encodable = EncodableCoordinate(coordinate: coordinate) let data = NSKeyedArchiver.archiveRootObject(encodable,toFile: somePath) 存储时每次都创建一个额外的对象未免太麻烦了,并且我也希望将这种方法和 想要做到这一点,先添加两个协议: protocol Encoded { associatedtype Encoder: NSCoding var encoder: Encoder { get } } protocol Encodable { associatedtype Value var value: Value? { get } } 并让两个类对应遵守这两个协议: extension EncodableCoordinate: Encodable { var value: Coordinate? { return coordinate } } extension Coordinate: Encoded { var encoder: EncodableCoordinate { return EncodableCoordinate(coordinate: self) } } 实现了以上内容之后,类型系统就知道如何在这些对象对之间进行值的转换了。 class Cache<T: Encoded> where T.Encoder: Encodable,T.Encoder.Value == T { //... } 对上文中提到的 最后需要完善的一部分是该类型的 func save(object: T) { NSKeyedArchiver.archiveRootObject(object.encoder,toFile: path) }
func fetchObject() -> T? { let fetchedEncoder = NSKeyedUnarchiver.unarchiveObject(withFile: storagePath) let typedEncoder = fetchedEncoder as? T.Encoder return typedEncoder?.value as T? } 现在,要使用这个 cache,只需要实例化一个对象并指定其类型为 let cache = Cache<Coordinate>(name: "coordinateCache") 生成了该对象之后,我们就可以透明地存取 coordinate 结构体了: cache.save(object: coordinate) 使用以上方法,我们可以通过
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |