编码复杂对象 swift 3.0
Encode complex object swift 3.0
我已经阅读了几篇文章并尝试了所有解决方案,但对我来说没有任何效果。
我正在使用这个复杂的数据结构,需要在文件中存储 DrawnObjects 数组。但是当它第一次编码一个本身是结构类型数组的变量时它崩溃了。有帮助吗?
[_SwiftValue encodeWithCoder:]: 无法识别的选择器发送到实例 0x1702668c0
enum ArchiverKeys : String
{
case imageView = "ImageView"
case stateArray = "StateArray"
case bezierPathArray = "BezierPathArray"
case reactangleArray = "ReactangleArray"
case deleted = "Deleted"
}
struct RectanglePath {
var point1: CGPoint
var point2: CGPoint
var point3: CGPoint
var point4: CGPoint
}
struct StateObject {
var isAdd = true
var path = String()
}
class DrawObject: NSObject , NSCoding {
var ImageView = UIImageView()
var arrStates = [StateObject]()
var arrBezierPaths = [UIBezierPath]()
var rects = [RectanglePath]()
var deleted = false
override init() {
ImageView = UIImageView()
arrStates = []
arrBezierPaths = []
rects = []
deleted = false
}
func encode(with archiver: NSCoder) {
archiver.encode(self.ImageView, forKey:ArchiverKeys.imageView.rawValue )
archiver.encode(self.arrStates, forKey: ArchiverKeys.stateArray.rawValue)
archiver.encode(self.arrBezierPaths, forKey:ArchiverKeys.bezierPathArray.rawValue )
archiver.encode(self.rects, forKey: ArchiverKeys.reactangleArray.rawValue)
archiver.encode(self.deleted, forKey: ArchiverKeys.deleted.rawValue)
}
required convenience init(coder unarchiver: NSCoder) {
self.init()
self.ImageView = unarchiver.decodeObject(forKey: ArchiverKeys.imageView.rawValue) as! UIImageView
self.arrStates = unarchiver.decodeObject(forKey: ArchiverKeys.stateArray.rawValue) as! [StateObject]
self.arrBezierPaths = unarchiver.decodeObject(forKey: ArchiverKeys.bezierPathArray.rawValue) as! [UIBezierPath]
self.rects = unarchiver.decodeObject(forKey: ArchiverKeys.reactangleArray.rawValue) as! [RectanglePath]
self.deleted = (unarchiver.decodeObject(forKey: ArchiverKeys.deleted.rawValue) != nil)
}
}
func saveArrayTo(_ directoryName: String , arrayToSave: NSArray) {
// let encodedData = NSKeyedArchiver.archivedData(withRootObject: arrayToSave)
NSKeyedArchiver.archiveRootObject(arrayToSave, toFile: directoryName)
}
func loadArrayFrom(_ directoryName: String ) -> NSArray? {
let result = NSKeyedUnarchiver.unarchiveObject(withFile: directoryName)
return result as? NSArray
}
你不能编码开箱即用的 Swift 结构,你必须添加一个计算 属性 和一个 init
方法来使结构 属性 列表兼容
struct StateObject {
var isAdd = true
var path = ""
init(propertyList : [String:Any]) {
self.isAdd = propertyList["isAdd"] as! Bool
self.path = propertyList["path"] as! String
}
var propertyListRepresentation : [String:Any] {
return ["isAdd" : isAdd, "path" : path]
}
}
现在您可以存档数组
archiver.encode(self.arrStates.map{[=11=].propertyListRepresentation}, forKey: ArchiverKeys.stateArray.rawValue)
并取消存档
let states = unarchiver.decodeObject(forKey: ArchiverKeys.stateArray.rawValue) as! [[String:Any]]
self.arrStates = states.map { StateObject(propertyList: [=12=]) }
或者保持 StateObject
不变,
中encode(with
替换行
archiver.encode(self.arrStates, forKey: ArchiverKeys.stateArray.rawValue)
和
let arrStatesAsPlist = arrStates.map { return ["isAdd" : [=14=].isAdd, "path" : [=14=].path] }
archiver.encode(arrStatesAsPlist, forKey:ArchiverKeys.stateArray.rawValue)
中init(coder
替换行
archiver.encode(self.arrStates, forKey: ArchiverKeys.stateArray.rawValue)
与
let arrStatesAsPlist = unarchiver.decodeObject(forKey: ArchiverKeys.stateArray.rawValue) as! [[String:Any]]
arrStates = arrStatesAsPlist.map { StateObject(isAdd: [=16=]["isAdd"] as! Bool, path: [=16=]["path"] as! String) }
备注:
由于您正在为所有属性分配默认值,因此您可以删除整个 init()
方法和 init(coder
.
中的 init()
调用
不要在 Swift 中使用 NSArray
。使用原生 Array
像 UIImageView
这样的 UI 元素不是一个好主意。存档图像数据。
我已经阅读了几篇文章并尝试了所有解决方案,但对我来说没有任何效果。
我正在使用这个复杂的数据结构,需要在文件中存储 DrawnObjects 数组。但是当它第一次编码一个本身是结构类型数组的变量时它崩溃了。有帮助吗?
[_SwiftValue encodeWithCoder:]: 无法识别的选择器发送到实例 0x1702668c0
enum ArchiverKeys : String
{
case imageView = "ImageView"
case stateArray = "StateArray"
case bezierPathArray = "BezierPathArray"
case reactangleArray = "ReactangleArray"
case deleted = "Deleted"
}
struct RectanglePath {
var point1: CGPoint
var point2: CGPoint
var point3: CGPoint
var point4: CGPoint
}
struct StateObject {
var isAdd = true
var path = String()
}
class DrawObject: NSObject , NSCoding {
var ImageView = UIImageView()
var arrStates = [StateObject]()
var arrBezierPaths = [UIBezierPath]()
var rects = [RectanglePath]()
var deleted = false
override init() {
ImageView = UIImageView()
arrStates = []
arrBezierPaths = []
rects = []
deleted = false
}
func encode(with archiver: NSCoder) {
archiver.encode(self.ImageView, forKey:ArchiverKeys.imageView.rawValue )
archiver.encode(self.arrStates, forKey: ArchiverKeys.stateArray.rawValue)
archiver.encode(self.arrBezierPaths, forKey:ArchiverKeys.bezierPathArray.rawValue )
archiver.encode(self.rects, forKey: ArchiverKeys.reactangleArray.rawValue)
archiver.encode(self.deleted, forKey: ArchiverKeys.deleted.rawValue)
}
required convenience init(coder unarchiver: NSCoder) {
self.init()
self.ImageView = unarchiver.decodeObject(forKey: ArchiverKeys.imageView.rawValue) as! UIImageView
self.arrStates = unarchiver.decodeObject(forKey: ArchiverKeys.stateArray.rawValue) as! [StateObject]
self.arrBezierPaths = unarchiver.decodeObject(forKey: ArchiverKeys.bezierPathArray.rawValue) as! [UIBezierPath]
self.rects = unarchiver.decodeObject(forKey: ArchiverKeys.reactangleArray.rawValue) as! [RectanglePath]
self.deleted = (unarchiver.decodeObject(forKey: ArchiverKeys.deleted.rawValue) != nil)
}
}
func saveArrayTo(_ directoryName: String , arrayToSave: NSArray) {
// let encodedData = NSKeyedArchiver.archivedData(withRootObject: arrayToSave)
NSKeyedArchiver.archiveRootObject(arrayToSave, toFile: directoryName)
}
func loadArrayFrom(_ directoryName: String ) -> NSArray? {
let result = NSKeyedUnarchiver.unarchiveObject(withFile: directoryName)
return result as? NSArray
}
你不能编码开箱即用的 Swift 结构,你必须添加一个计算 属性 和一个 init
方法来使结构 属性 列表兼容
struct StateObject {
var isAdd = true
var path = ""
init(propertyList : [String:Any]) {
self.isAdd = propertyList["isAdd"] as! Bool
self.path = propertyList["path"] as! String
}
var propertyListRepresentation : [String:Any] {
return ["isAdd" : isAdd, "path" : path]
}
}
现在您可以存档数组
archiver.encode(self.arrStates.map{[=11=].propertyListRepresentation}, forKey: ArchiverKeys.stateArray.rawValue)
并取消存档
let states = unarchiver.decodeObject(forKey: ArchiverKeys.stateArray.rawValue) as! [[String:Any]]
self.arrStates = states.map { StateObject(propertyList: [=12=]) }
或者保持 StateObject
不变,
中
encode(with
替换行archiver.encode(self.arrStates, forKey: ArchiverKeys.stateArray.rawValue)
和
let arrStatesAsPlist = arrStates.map { return ["isAdd" : [=14=].isAdd, "path" : [=14=].path] } archiver.encode(arrStatesAsPlist, forKey:ArchiverKeys.stateArray.rawValue)
中
init(coder
替换行archiver.encode(self.arrStates, forKey: ArchiverKeys.stateArray.rawValue)
与
let arrStatesAsPlist = unarchiver.decodeObject(forKey: ArchiverKeys.stateArray.rawValue) as! [[String:Any]] arrStates = arrStatesAsPlist.map { StateObject(isAdd: [=16=]["isAdd"] as! Bool, path: [=16=]["path"] as! String) }
备注:
由于您正在为所有属性分配默认值,因此您可以删除整个
中的init()
方法和init(coder
.init()
调用不要在 Swift 中使用
NSArray
。使用原生Array
像
UIImageView
这样的 UI 元素不是一个好主意。存档图像数据。