本文介绍了当 func encode(with 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 {

报告的error:

使用 console 日志:

libc++abi.dylib:以 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:

The code here I archive my 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)
                
            })

My debug when archiveRootObject:

控制台日志:

(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

我已经在simulatordevice 中测试过,在simulator 中不存在这个问题,在真正的device 中问题出来了.

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

推荐答案

试试这个来解决你的问题

Try this for your Question

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

了解更多信息

让我们详细讨论这个问题

Let Discuss this problem in details

例如,这是我的枚举:

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.

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的情况下你不能直接编码enum B'Coz它是用户定义的数据类型但是rawValue必须是内置数据类型像 Int、String、Float.....等等.这就是为什么当您尝试对 enum 进行编码时,您需要使用 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 encode(with aCoder: NSCoder) 方法中的存档对象与真实版本中的 swift 枚举崩溃时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-24 03:13