2017-05-25 74 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