在Swift中使用unarchiveObjectWithData时的不确定行为

时间:2016-04-15 09:19:27

标签: ios swift nskeyedarchiver nskeyedunarchiver

我在Swift中遇到以下代码问题。我从我的一个应用程序中提取了代码并设置了一个Playground来测试它的行为。

有时以下行成功,有时会失败:

if var selectedCards = NSKeyedUnarchiver.unarchiveObjectWithData(data) as? [Account : Card] {

Playground中的运行之间没有任何变化。

如果有人能帮助我,我将非常感激。它让我发疯了!

当Playground中的行失败时,它会失败,并显示以下错误:

  

执行被中断,原因是:EXC_BAD_INSTRUCTION   (code = EXC_I386_INVOP,subcode = 0x0

当我的应用程序中的行失败时,它会失败并出现相同的错误,并在调试控制台中打印出来:

  

致命错误:在解包可选值时意外发现nil

游乐场

import Foundation

帐户类

class Account: NSObject, Comparable, NSCoding, NSCopying {

    var email: String = ""
    var locked: Bool = false

    override var hashValue: Int {
        return email.hash
    }

    required init(email: String) {
        super.init()
        self.email = email
        self.locked = false
    }

    required init?(coder decoder: NSCoder) {
        email = decoder.decodeObjectForKey("email") as! String
        locked = decoder.decodeBoolForKey("locked")
    }

    func encodeWithCoder(coder: NSCoder) {
        coder.encodeObject(email, forKey: "email")
        coder.encodeBool(locked, forKey: "locked")
    }

    func copyWithZone(zone: NSZone) -> AnyObject {
        let account = self.dynamicType.init(email: self.email)
        account.email = self.email
        account.locked = self.locked
        return account
    }

    override func isEqual(object: AnyObject?) -> Bool {
        guard let account = object as? Account else { return false }
        return account == self
    }
}

func ==(lhs: Account, rhs: Account) -> Bool {
    let emailEqual = lhs.email == rhs.email
    return emailEqual
}

func <(lhs: Account, rhs: Account) -> Bool {
    return lhs.email < rhs.email
}

卡片类

class Card: NSObject, Comparable, NSCoding {

    var id: String = ""
    var name: String = ""

    override var hashValue: Int {
        return id.hash
    }

    init(id: String, name: String) {
        super.init()
        self.id = id
        self.name = name
    }

    required init?(coder decoder: NSCoder) {
        id = decoder.decodeObjectForKey("id") as! String
        name = decoder.decodeObjectForKey("name") as! String
    }

    func encodeWithCoder(coder: NSCoder) {
        coder.encodeObject(id, forKey: "id")
        coder.encodeObject(name, forKey: "name")
    }

    override func isEqual(object: AnyObject?) -> Bool {
        guard let card = object as? Card else { return false }
        return card == self
    }
}

func ==(lhs: Card, rhs: Card) -> Bool {
    let idEqual = lhs.id == rhs.id
    let nameEqual = lhs.name == rhs.name
    return idEqual && nameEqual
}

func <(lhs: Card, rhs: Card) -> Bool {
    if lhs.name == rhs.name {
        return lhs.id < rhs.id
    }
    return lhs.name < rhs.name
}

测试

let account = Account(email: "user@domain.com")
let card = Card(id: "1", name: "Card 1")

let map: [Account : Card] = [account : card]

let data = NSKeyedArchiver.archivedDataWithRootObject(map)

if var selectedCards = NSKeyedUnarchiver.unarchiveObjectWithData(data) as? [Account : Card] {
    let selectedCard = Card(id: "2", name: "Card 2")
    selectedCards[account] = selectedCard

    print("Success")
}

0 个答案:

没有答案