Ios 在Swift中使用包含数据的非归档对象时的不确定行为
我在Swift中遇到以下代码问题。我从我的一个应用程序中提取了代码,并设置了一个游乐场来测试它的行为 下面这行有时成功,有时失败:Ios 在Swift中使用包含数据的非归档对象时的不确定行为,ios,swift,nskeyedarchiver,nskeyedunarchiver,Ios,Swift,Nskeyedarchiver,Nskeyedunarchiver,我在Swift中遇到以下代码问题。我从我的一个应用程序中提取了代码,并设置了一个游乐场来测试它的行为 下面这行有时成功,有时失败: if var selectedCards = NSKeyedUnarchiver.unarchiveObjectWithData(data) as? [Account : Card] { 在操场上跑步之间没有任何变化 如果有人能帮助我,我将不胜感激。这快把我逼疯了 当线路在操场发生故障时,它会出现以下错误: 执行被中断,原因:EXC\u BAD\u指令 (代码=E
if var selectedCards = NSKeyedUnarchiver.unarchiveObjectWithData(data) as? [Account : Card] {
在操场上跑步之间没有任何变化
如果有人能帮助我,我将不胜感激。这快把我逼疯了
当线路在操场发生故障时,它会出现以下错误:
执行被中断,原因:EXC\u BAD\u指令
(代码=EXC_I386_INVOP,子代码=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
}
…as?[帐户:卡]
:查看这两个类所需的可故障初始化程序,例如,强制类型转换电子邮件=…as!String
和id=…as!String
。如果解码器(例如,对于密钥“id”
),这些将不会失败并返回nil
在强制强制转换(as
)之前,产生nil
,相反,它们会崩溃。尝试使用对象解码的安全展开(例如可选绑定)重新写入这些初始化器,如果解码失败(因此初始化失败而不是崩溃),则返回nil
。怀疑我可能只需要添加@objc(账户)在账户类之前,以及@objc(卡)在Card类之前,使用未损坏的类名Hanks dfri。这绝对值得一做。但是,它应该是有效的,这并不能解释为什么当数据相同时它有时有效,有时无效。NSKeyedArchiver
与此无关,因为我们可以将相同的问题归结为只是显式地尝试创建将NSDictionary
作为[帐户:卡]
,即让map:NSDictionary=[帐户:卡]
(或只是[帐户:“foo”]
)。这也会偶尔失败,出现致命错误“在打开可选值时意外发现零”。自然地,NSDictionary
不能保存nil
的键,但我无法解释为什么account
在作为键/值输入NSDictionary
时会不确定地产生nil
。似乎相关。
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")
}