2017-05-20 6 views
0

나는 NSKeyedArchiver를 사용하여 plist 파일에 문서 디렉토리에 저장되는 지폐의 몇 가지 인스턴스를 포함하는 Bill 클래스가 있습니다.개체가 이미 저장된 경우 기존 모델에 매개 변수를 추가하는 방법은 무엇입니까?

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를 기록하기위한 추가 매개 변수를 추가하려고합니다. 이 때문에이없는 기존 법안 객체를로드하려고에

status = aDecoder.decodeObject(forKey: "Status") as! 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() { 
    ... 
} 

는 오류가 발생합니다 매개 변수.

이 매개 변수를 삭제하고 처음부터 다시 만들 필요없이 기존 개체에 추가 할 수 있습니까?

+0

는 사용하지 마십시오 디폴트 값을 제공하기 위해 전무 병합 연산자를 사용할 수 있습니다 내리 뜬 강제; nil coalescing operator로 가능한 조건부 Downcast를 사용하십시오. – Paulw11

+0

그러면 상태가 선택적 값을 취할 수 없으므로 컴파일러 오류가 발생합니다. – Hutch

답변

3

개체에 값이 없으므로 강제 다운 캐스트가 아닌 선택적 다운 캐스트를 사용해야합니다. status는 선택하지 않기 때문에, 당신은

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

그러나 이것은 인식 할 수없는 선택자를 인스턴스 encodeWithCoder로 보냈습니다. 나는 이것이 enum 인코딩과 별도의 질문과 관련이있을 것이라고 생각한다. – Hutch