2017-05-20 43 views
0

我有一個Bill類,其中包含一些使用NSKeyedArchiver保存在plist文件中的賬單實例。如何在已保存對象時將參數添加到現有模型?

class Bill: NSObject, NSCoding { 

    required init?(coder aDecoder: NSCoder) { 
    name = aDecoder.decodeObject(forKey: "Name") as! String 
    moPayment = aDecoder.decodeDouble(forKey: "Payment") 
    super.init() 
    } 

    override init() { 
    super.init() 
    } 

    var name = "Bill Name" 
    var moPayment = 0.0 

    func encode(with aCoder: NSCoder) { 
    aCoder.encode(name, forKey: "Name") 
    aCoder.encode(moPayment, forKey: "Payment") 
    } 
} 

func saveBillItems(_ bills: [Bill]) { 
    let data = NSMutableData() 
    let archiver = NSKeyedArchiver(forWritingWith: data) 
    archiver.encode(bills, forKey: "BillItems") 
    archiver.finishEncoding() 
    data.write(to: dataFilePath(), atomically: true) 
} 

func loadBillItems() { 
    let path = dataFilePath() 
    if let data = try? Data(contentsOf: path) { 

     let unarchiver = NSKeyedUnarchiver(forReadingWith: data) 
     bills = unarchiver.decodeObject(forKey: "BillItems") as! [Bill] 
     unarchiver.finishDecoding() 
    } 
} 

所有這些按預期工作,但現在我試圖添加一個額外的參數來記錄paidStatus。

class Bill: NSObject, NSCoding { 

    required init?(coder aDecoder: NSCoder) { 
    ... 
    status = aDecoder.decodeObject(forKey: "Status") as! PaidStatus 
    super.init() 
    } 

    ... 

    var status = PaidStatus.unpaid 

    enum PaidStatus { 
    case overdue 
    case upcoming 
    case unpaid 
    case paid 
    } 

    ... 

    func encode(with aCoder: NSCoder) { 
    ... 
    aCoder.encode(status, forKey: "Status") 
    } 
} 

func saveBillItems(_ bills: [Bill]) { 
    ... 
} 

func loadBillItems() { 
    ... 
} 

當我現在嘗試運行應用程序,我得到一個錯誤:「意外地發現零...」

status = aDecoder.decodeObject(forKey: "Status") as! PaidStatus 

在試圖加載不具備這種現有法案的對象參數。

有沒有辦法將此參數添加到我的現有對象,而不必刪除它們並從頭重新創建它們?

+0

不要使用強制垂頭喪氣;使用一個條件Downcast可能與一個零合併運算符 – Paulw11

+0

這樣做會給我一個編譯器錯誤,因爲狀態不能帶可選值。 – Hutch

回答

3

由於您的對象可能沒有值,因此您需要使用可選的向下轉換,而不是強制向下轉換。由於status是不可選的,你可以用一個零合併運算提供一個默認值

status = aDecoder.decodeObject(forKey: "Status") as? PaidStatus ?? .unpaid 
+0

這似乎工作,但我得到一個無法識別的選擇器發送到實例encodeWithCoder。我相信這可能與編碼一個枚舉相關,然後是一個單獨的問題。 – Hutch

相關問題