When archive object in the func encode(with aCoder: NSCoder) method crashed with swift enum in real revice

旧街凉风 提交于 2019-12-31 00:59:07

问题


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 {

The reported error:

With the console log:

libc++abi.dylib: terminating with uncaught exception of type NSException

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

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:

The console 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.


回答1:


Try this for your Question

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

For More Information

Let Discuss this problem in details

For example, this is my Enum:

enum PieceType : Int {
    case empty
    case notEmpty
}

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

    }

}

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.

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

I Hope you will get point.



来源:https://stackoverflow.com/questions/41116832/when-archive-object-in-the-func-encodewith-acoder-nscoder-method-crashed-with

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!