我在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")
}