当 func encode(with aCoder: NSCoder) 方法中的存档对象在实际 revice 中与 swift 枚举崩溃时
When archive object in the func encode(with aCoder: NSCoder) method crashed with swift enum in real revice
在我的 singleton
class 中,我这里有一个 swift
枚举:
import UIKit
enum UserType {
case terant //
case normalUser //
case normalUserFinancialer //
}
@objc(UserStaticSwift)
class UserStaticSwift:NSObject, NSCoding {
报道error
:
随着 console
日志:
libc++abi.dylib: terminating with uncaught exception of type NSException
在encode
中:
func encode(with aCoder: NSCoder) {
aCoder.encode(islogin, forKey: "islogin")
aCoder.encode(type!, forKey: "type") // crash here in real device
aCoder.encode(forOcType, forKey: "forOcType")
aCoder.encode(username, forKey: "username")
aCoder.encode(password, forKey: "password")
aCoder.encode(userId, forKey: "userId")
这里的code
我存档我的userStatic
:
userStatic.addUserInfo(type: userStatic.type!, dic: userInfoDic, closure: { (void) in
// success then archive `userStatic`
let paths:NSArray = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true) as NSArray
let path = paths.firstObject
let homePath = "\(path)/\(Global.archive_userStaticData)"
let _ = NSKeyedArchiver.archiveRootObject(userStatic, toFile: homePath)
})
我的 debug
当 archiveRootObject
:
console
日志:
(lldb) po NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true) as NSArray
error: Couldn't materialize: couldn't get the value of void: extracting data from value failed
error: errored out in DoExecute, couldn't PrepareToExecuteJITExpression
(lldb) po homePath
error: Couldn't materialize: couldn't get the value of void: extracting data from value failed
error: errored out in DoExecute, couldn't PrepareToExecuteJITExpression
我在 simulator
和 device
中测试过,在 simulator
中不存在问题,实际上 device
问题出现了。
试试这个解决你的问题
func encode(with aCoder: NSCoder) {
aCoder.encode(type.rawValue, forKey: "type")
}
了解更多信息
让我们详细讨论这个问题
例如,这是我的枚举:
enum PieceType : Int {
case empty
case notEmpty
}
这是我的对象,它是 NSObject
的子对象
class Piece: NSObject, NSCoding {
var islogin: Bool
var type: PieceType
var username: String!
var password: String!
override init() {
islogin = false
type = PieceType.empty
username = ""
password = ""
}
required init(coder aDecoder: NSCoder) {
islogin = aDecoder.decodeBool(forKey: "islogin")
type = PieceType(rawValue: aDecoder.decodeObject(forKey: "type") as! Int)!
username = aDecoder.decodeObject(forKey: "username") as! String
password = aDecoder.decodeObject(forKey: "password") as! String
}
func encode(with aCoder: NSCoder) {
aCoder.encode(islogin, forKey: "islogin")
aCoder.encode(type.rawValue, forKey: "type")
aCoder.encode(username, forKey: "username")
aCoder.encode(password, forKey: "password")
}
}
当您调用 NSKeyedArchiver.archiveRootObject(::)
时,它将调用 func encode(with aCoder: NSCoder)
方法并将您的 NSObject
转换为数据 当您尝试取消归档对象时,它将调用 init(coder aDecoder: NSCoder)
方法,并且使用 Key.
将 Data 转换为 NSObject
但在 Enum
情况下你不能直接编码 enum
B'因为它是用户定义数据类型但 rawValue
必须是内置数据类型,如 Int、String、Float .....很快。
这就是为什么当你尝试编码 enum
时你需要使用 rawValue
希望你能得到分数。
在我的 singleton
class 中,我这里有一个 swift
枚举:
import UIKit
enum UserType {
case terant //
case normalUser //
case normalUserFinancialer //
}
@objc(UserStaticSwift)
class UserStaticSwift:NSObject, NSCoding {
报道error
:
随着 console
日志:
libc++abi.dylib: terminating with uncaught exception of type NSException
在encode
中:
func encode(with aCoder: NSCoder) {
aCoder.encode(islogin, forKey: "islogin")
aCoder.encode(type!, forKey: "type") // crash here in real device
aCoder.encode(forOcType, forKey: "forOcType")
aCoder.encode(username, forKey: "username")
aCoder.encode(password, forKey: "password")
aCoder.encode(userId, forKey: "userId")
这里的code
我存档我的userStatic
:
userStatic.addUserInfo(type: userStatic.type!, dic: userInfoDic, closure: { (void) in
// success then archive `userStatic`
let paths:NSArray = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true) as NSArray
let path = paths.firstObject
let homePath = "\(path)/\(Global.archive_userStaticData)"
let _ = NSKeyedArchiver.archiveRootObject(userStatic, toFile: homePath)
})
我的 debug
当 archiveRootObject
:
console
日志:
(lldb) po NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true) as NSArray
error: Couldn't materialize: couldn't get the value of void: extracting data from value failed
error: errored out in DoExecute, couldn't PrepareToExecuteJITExpression
(lldb) po homePath
error: Couldn't materialize: couldn't get the value of void: extracting data from value failed
error: errored out in DoExecute, couldn't PrepareToExecuteJITExpression
我在 simulator
和 device
中测试过,在 simulator
中不存在问题,实际上 device
问题出现了。
试试这个解决你的问题
func encode(with aCoder: NSCoder) {
aCoder.encode(type.rawValue, forKey: "type")
}
了解更多信息
让我们详细讨论这个问题
例如,这是我的枚举:
enum PieceType : Int {
case empty
case notEmpty
}
这是我的对象,它是 NSObject
class Piece: NSObject, NSCoding {
var islogin: Bool
var type: PieceType
var username: String!
var password: String!
override init() {
islogin = false
type = PieceType.empty
username = ""
password = ""
}
required init(coder aDecoder: NSCoder) {
islogin = aDecoder.decodeBool(forKey: "islogin")
type = PieceType(rawValue: aDecoder.decodeObject(forKey: "type") as! Int)!
username = aDecoder.decodeObject(forKey: "username") as! String
password = aDecoder.decodeObject(forKey: "password") as! String
}
func encode(with aCoder: NSCoder) {
aCoder.encode(islogin, forKey: "islogin")
aCoder.encode(type.rawValue, forKey: "type")
aCoder.encode(username, forKey: "username")
aCoder.encode(password, forKey: "password")
}
}
当您调用 NSKeyedArchiver.archiveRootObject(::)
时,它将调用 func encode(with aCoder: NSCoder)
方法并将您的 NSObject
转换为数据 当您尝试取消归档对象时,它将调用 init(coder aDecoder: NSCoder)
方法,并且使用 Key.
NSObject
但在 Enum
情况下你不能直接编码 enum
B'因为它是用户定义数据类型但 rawValue
必须是内置数据类型,如 Int、String、Float .....很快。
这就是为什么当你尝试编码 enum
时你需要使用 rawValue
希望你能得到分数。