当func编码中的归档对象(使用aCoder:NSCoder)方法在真实的revice中使用swift enum崩溃时
在我的singleton
课程中,我有一个swift
枚举:
import UIKit enum UserType { case terant // case normalUser // case normalUserFinancialer // } @objc(UserStaticSwift) class UserStaticSwift:NSObject, NSCoding {
报告的error
:
使用console
日志:
libc ++ abi.dylib:以NSException类型的未捕获exception终止
在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) })
我在archiveRootObject
时debug
:
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’Coz它是用户定义数据类型但是rawValue
必须是内置数据类型,如Int,String,Float …..所以。 这就是为什么当你尝试编码enum
你需要使用rawValue
我希望你能得到点。