【问题标题】:Swift3: [String: AnyObject] using NSCoding protocol to save with NSUserDefaultsSwift3: [String: AnyObject] 使用 NSCoding 协议使用 NSUserDefaults 保存
【发布时间】:2016-09-29 16:18:46
【问题描述】:

我有我的自定义类:

private class PendingRequest : NSObject, NSCoding
{
    var route : String!
    var params: [String: AnyObject]!

    init(route: String, params: [String: AnyObject])
    {
        self.route = route
        self.params = params
    }
    required init(coder aDecoder: NSCoder)
    {
        self.route = aDecoder.decodeObject(forKey: "route") as! String
        self.params = aDecoder.decodeObject(forKey: "params") as! [String: AnyObject]
    }

    public func encode(with coder: NSCoder)
    {
        coder.encode(route, forKey: "route")
        coder.encode(params, forKey: "params")
    }
}

这是我保存PendingRequest列表的方法:

private static func savePendingRequests(requestsToSend: [PendingRequest])
{
    let data = NSKeyedArchiver.archivedData(withRootObject: requestsToSend!)
    UserDefaults.standard.set(data, forKey: self.requestsToSendDefaultsString)
}

这是我尝试检索它的方法:

let data = UserDefaults.standard.data(forKey: requestsToSendDefaultsString)
let requests = NSKeyedUnarchiver.unarchiveObject(with: data!) as! [PendingRequest]
return requests

但是在检索我的数据时我的代码崩溃了...保存工作正常,但无法检索...有什么想法吗?

编辑:这是我的Crashlytics 错误:

*** -[NSKeyedUnarchiver decodeObjectForKey:]: cannot decode object of class (_TtCC6Versus9VersusAPIP33_8D2B8AA415FDC4F8DFAF29D7ECE33C1F14PendingRequest) for key (NS.objects); the class may be defined in source code or a library that is not linked

解决方案:

我的班级PendingRequestfileprivate,因此NSKeyedUnarchiver 无法访问它,因此崩溃了...感谢您的帮助。

【问题讨论】:

  • 能否添加崩溃日志表示调试控制台中正在打印的错误。
  • 考虑 AnyObject 已更改为 Any,相当于 Objective-C 的 id
  • @NiravD 就是这样,我在控制台中没有打印任何内容...
  • 编辑:使用 Crashlytics,我设法获得了一些信息...请参阅我对原始帖子的编辑。

标签: swift nsuserdefaults nscoding


【解决方案1】:

有些地方是不正确的

您忘记在初始化程序中调用 super.init()

init(route: String, params: [String: AnyObject])
{
    self.route = route
    self.params = params
    super.init()
}
required init(coder aDecoder: NSCoder)
{
    self.route = aDecoder.decodeObject(forKey: "route") as? String
    self.params = aDecoder.decodeObject(forKey: "params") as? [String: AnyObject]


    // Check if route and params are what you expected here


    super.init()
}

你有一个调用“self”的静态方法,我不确定这是否有效,你仍然可以有一个静态键或全局键。 另外,您正在解开一个非可选值“requestsToSend”。 我想这会解决它。

private static func savePendingRequests(requestsToSend:[PendingRequest])
{
     let data = NSKeyedArchiver.archivedData(withRootObject: requestsToSend)
     UserDefaults.standard.set(data, forKey: "AStaticKey")
}

然后检索应该工作。 (我添加了一些安全检查)

guard let data = UserDefaults.standard.data(forKey: "AStaticKey"), 
      let requests = NSKeyedUnarchiver.unarchiveObject(with: data) as? [PendingRequest] else {
         return [PendingRequest]()
      }
return requests

【讨论】:

  • 感谢您的回答。事实上,我忘记了super.int()。关于键,它是一个静态变量(字符串)。但这并没有解决问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-15
  • 1970-01-01
相关资源
最近更新 更多