2017-04-08 18 views
3
import UIKit 

class Foo: NSObject, NSCoding { 
    var cx: [Character : Int] 

    init(cx: [Character : Int]) { 
     self.cx = cx 
    } 

    // MARK: - <NSCoding> 

    required convenience init(coder aDecoder: NSCoder) { 
     let cx = aDecoder.decodeObject(forKey: "cxKey") as! [Character : Int] 
     self.init(cx: cx) 
    } 

    func encode(with aCoder: NSCoder) { 
     aCoder.encode(cx, forKey: "cxKey") 
    } 
} 

電話:如何在Swift 3中使用NSCoder對[Character:Int]屬性進行編碼?

class ViewController: UIViewController { 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     // Do any additional setup after loading the view, typically from a nib. 

     var foo = Foo(cx: ["C": 5, "X": 6]) 

     let encodedData = NSKeyedArchiver.archivedData(withRootObject: foo) 
     print("encodedData: \(encodedData))") 

     if let foo1 = NSKeyedUnarchiver.unarchiveObject(with: encodedData) as? Foo { 
      print("cx = ", foo1.cx) 
     } else{ 
      print("There is an issue") 
     } 
    } 
} 

Xcode中拋出一個錯誤:***終止應用程序由於未捕獲的異常 'NSInvalidArgumentException',原因是:「 - [_ SwiftValue encodeWithCoder:]:無法識別的選擇發送到實例

+0

你是怎麼稱呼它的? – Rikh

+0

對不起,添加它 – Max

回答

2

原因

這是因爲在cxCharacter -typed鍵將被作爲盒裝對象_SwiftValue其中將被髮送encodeWithCoder:,這導致無法識別的選擇器異常。

看到的SwiftValue.h頂部的評論:

This implements the Objective-C class that is used to carry Swift values that have been bridged to Objective-C objects without special handling. The class is opaque to user code, but is NSObject - and NSCopying - conforming and is understood by the Swift runtime for dynamic casting back to the contained type.

解決方案

如果你可以改變的cx類型[String : Int],一切都會開箱即用(沒有雙關語意) 。

否則你必須在Foo.encode(with:)中將cx轉換爲可編碼的東西(例如[String : Int]),反之亦然。

有關某些代碼,請參閱How do I encode Character using NSCoder in swift?How do I encode enum using NSCoder in swift?

+0

感謝您的回答 – Max

相關問題