在 UserDefaults 中存储 OpaquePointer 类型

Storing OpaquePointer type in UserDefaults

我正在 Xcode 12 和 Swift 5 环境中构建 iOS 应用程序。

我需要在视图消失之前(或应用程序关闭之前)存储一个 OpaquePointer 类型变量(下面代码中的“self.loggers”),并在视图出现时(应用程序运行时)检索它. 我尝试如下使用 UserDefault,

// Storing(In viewWillDisappear)
do {
            encodedData = try NSKeyedArchiver.archivedData(withRootObject: self.loggers, requiringSecureCoding: false)
            UserDefaults.standard.set(encodedData, forKey: "accelLoggerID")
        } catch {
            print("archiving error")
        }
...

// Retrieving(In viewDidLoad)
if let decodedData = UserDefaults.standard.object(forKey: "acceleration") as? Data {
            do {
                self.loggers = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(decodedData) as? [String:OpaquePointer] ?? [:]} catch {
                    print("unarchiving error")
                }
        } else {
            self.loggers = [:]
            print("No value in Userdefault. [viewDidLoad]")
        }

但是,NSKeyedArchiver 无法对此类进行编码。在那之后,我做了一个 class 来包装变量。

class LoggerWrapper {
    var loggers: [String : OpaquePointer]
    init(loggerDic: [String : OpaquePointer]) {
        loggers = loggerDic
    }
}

并像这样更改了我的代码

self.loggers = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(decodedData) as? LoggerWrapper ?? LoggerWrapper(loggerDic: [:])} catch {
                    print("unarchiving error")
                }

但是,这会在调用 NSKeyedArchiver.archivedData 时给出 SIGABRT。 有没有办法在 UserDefaults 中存储 Opaquepointer 类型?如果不是,使用核心数据是否可以解决这个问题?

谢谢。

您可能需要将指针转换为 Int 位模式。 Int 上有一个初始值设定项:let intBitPattern = Int(bitPattern: opaquePointer)OpaquePointer 上还有一个初始化程序,它采用 Int 位模式:let opaquePointer = OpaquePointer(bitPattern: intBitPattern)。 因此,您需要在存储之前和读取之后转换字典中的值(例如使用 compactMapValues)。

使用 Dictionary<String, Int>,您应该可以直接将其存储在 UserDefaults 中,而不需要 NSKeyedArchiverNSKeyedUnarchiver


旁注: 指针不是“长寿的”。因此将其存储在 UserDefaults 中仅在您的应用程序的生命周期内有效。一旦您的应用程序重新启动,指针可能不再有效。