本文介绍了当func编码(使用aCoder:NSCoder)方法中的归档对象在真实的设备中与swift枚举崩溃时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的 singleton 类中,我有一个 swift 枚举:

In my singleton class, I have a swift enum here:

import UIKit

enum UserType {
    case terant  // 
    case normalUser  // 
    case normalUserFinancialer  // 
}

@objc(UserStaticSwift)
class UserStaticSwift:NSObject, NSCoding {

报告的错误

使用控制台 log:

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")

代码这里我存档我的 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

控制台 log:

(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

我已经在模拟器设备模拟器中,问题不存在,在设备中出现问题。

I have tested in simulator and device, in the simulator the issue not exist, in real device the issue comes out.

推荐答案

尝试这样做问题

func encode(with aCoder: NSCoder) {
    aCoder.encode(type.rawValue, forKey: "type")
}

更多信息

请详细讨论此问题

例如,这是我的枚举:

enum PieceType : Int {
    case empty
    case notEmpty
}

这是我的Object,它是 NSObject

And this is my Object which is child of 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)方法并将数据转换为 NSObject 通过使用Key。

When you call NSKeyedArchiver.archiveRootObject(::) it will call func encode(with aCoder: NSCoder) method and convert your NSObject to Data And when you try to Unarchive your object it will call init(coder aDecoder: NSCoder) method and convert Data to NSObject by using Key.

但是在枚举案例中,您无法编码 enum 直接B'Coz是用户定义数据类型,但 rawValue 必须是内置的数据类型,如Int,String,Float .. ...所以。
这就是为什么当您尝试编码枚举时,您需要使用 rawValue

But in Enum case you can not encode enum directly B'Coz it is User Define data type but rawValue is must be inbuilt data type like Int, String,Float.....So on.that's why when you try to encode enum you need to use rawValue

我希望你能得到点。

这篇关于当func编码(使用aCoder:NSCoder)方法中的归档对象在真实的设备中与swift枚举崩溃时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-19 00:46