2017-05-25 32 views
0

我已经阅读了几篇文章,并尝试了每种解决方案,在我的情况下没有任何工作。编码复杂的对象swift 3.0

我正在使用这个复杂的数据结构,并需要将DrawnObjects数组存储在文件中。但是当它首先编码一个变量本身就是一个Structure类型的数组时,它会崩溃。任何帮助?

[_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 
    } 

回答

3

不能编码斯威夫特结构开箱即用,你必须添加一个计算的性能和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{$0.propertyListRepresentation}, forKey: ArchiverKeys.stateArray.rawValue) 

和解除封存

let states = unarchiver.decodeObject(forKey: ArchiverKeys.stateArray.rawValue) as! [[String:Any]] 
self.arrStates = states.map { StateObject(propertyList: $0) } 

或者离开StateObject不变,

  • encode(with更换线

    archiver.encode(self.arrStates, forKey: ArchiverKeys.stateArray.rawValue) 
    

    let arrStatesAsPlist = arrStates.map { return ["isAdd" : $0.isAdd, "path" : $0.path] } 
    archiver.encode(arrStatesAsPlist, forKey:ArchiverKeys.stateArray.rawValue) 
    
  • init(coder

    let arrStatesAsPlist = unarchiver.decodeObject(forKey: ArchiverKeys.stateArray.rawValue) as! [[String:Any]] 
    arrStates = arrStatesAsPlist.map { StateObject(isAdd: $0["isAdd"] as! Bool, path: $0["path"] as! String) } 
    

注替换行

archiver.encode(self.arrStates, forKey: ArchiverKeys.stateArray.rawValue) 

  • 由于您将默认值分配给所有属性,因此可以删除整个init()方法和init()调用init(coder

  • 不要在Swift中使用NSArray。使用本机Array

  • 归档像UIImageView这样的UI元素并不是一个好主意。归档图像数据。

+0

谢谢@vadian我会试试这个,让你知道。它的工作原理是 – ChanWarde

+0

OMG。非常感谢@vadian。现在我正在努力保存图像而不是图像视图。 – ChanWarde