为了账号安全,请及时绑定邮箱和手机立即绑定

使用NSCoding将自定义Swift类保存到UserDefaults

使用NSCoding将自定义Swift类保存到UserDefaults

MMMHUHU 2019-07-26 15:59:00
使用NSCoding将自定义Swift类保存到UserDefaults我目前正在尝试将自定义Swift类保存到NSUserDefaults。这是我的Playground的代码:import Foundationclass Blog : NSObject, NSCoding {     var blogName: String?     override init() {}     required init(coder aDecoder: NSCoder) {         if let blogName = aDecoder.decodeObjectForKey("blogName") as? String {             self.blogName = blogName        }     }     func encodeWithCoder(aCoder: NSCoder) {         if let blogName = self.blogName {             aCoder.encodeObject(blogName, forKey: "blogName")         }     }}var blog = Blog()blog.blogName = "My Blog"let ud = NSUserDefaults.standardUserDefaults()    ud.setObject(blog, forKey: "blog")当我运行代码时,我收到以下错误执行被中断,原因:信号SIGABRT。在最后一行(ud.setObject...)在带有消息的应用程序中,相同的代码也会崩溃“属性列表格式无效:200(属性列表不能包含'CFType'类型的对象)”有人可以帮忙吗?我在Maverick上使用Xcode 6.0.1。谢谢。
查看完整描述

3 回答

?
动漫人物

TA贡献1815条经验 获得超10个赞

第一个问题是你必须确保你有一个非破坏的类名:

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

然后,您必须先将对象编码(转换为NSData),然后才能将其存储到用户默认值中:

ud.setObject(NSKeyedArchiver.archivedDataWithRootObject(blog), forKey: "blog")

同样,要恢复对象,您需要取消归档它:

if let data = ud.objectForKey("blog") as? NSData {
    let unarc = NSKeyedUnarchiver(forReadingWithData: data)
    unarc.setClass(Blog.self, forClassName: "Blog")
    let blog = unarc.decodeObjectForKey("root")}

请注意,如果您没有在操场上使用它,那么您可以手动注册课程,这样会更简单:

if let data = ud.objectForKey("blog") as? NSData {
    let blog = NSKeyedUnarchiver.unarchiveObjectWithData(data)}


查看完整回答
反对 回复 2019-07-26
?
森林海

TA贡献2011条经验 获得超2个赞

在Swift 4中,使用Codable。

在您的情况下,请使用以下代码。

class Blog : Codable {

   var blogName: String?}

现在创建它的对象。例如:

var blog = Blog()blog.blogName = "My Blog"

现在编码如下:

if let encoded = try? JSONEncoder().encode(blog) {
    UserDefaults.standard.set(encoded, forKey: "blog")}

并解码它像这样:

if let blogData = UserDefaults.standard.data(forKey: "blog"),
    let blog = try? JSONDecoder().decode(Blog.self, from: blogData) {}


查看完整回答
反对 回复 2019-07-26
?
ABOUTYOU

TA贡献1812条经验 获得超5个赞

正如@ dan-beaulieu建议我回答我自己的问题:

这是现在的工作代码:

注意:代码在Playgrounds中工作时不需要解析类名。

import Foundationclass Blog : NSObject, NSCoding {

    var blogName: String?

    override init() {}

    required init(coder aDecoder: NSCoder) {
        if let blogName = aDecoder.decodeObjectForKey("blogName") as? String {
            self.blogName = blogName        }
    }

    func encodeWithCoder(aCoder: NSCoder) {
        if let blogName = self.blogName {
            aCoder.encodeObject(blogName, forKey: "blogName")
        }
    }}let ud = NSUserDefaults.standardUserDefaults()var blog = Blog()blog.blogName = "My Blog"ud.setObject(NSKeyedArchiver.archivedDataWithRootObject(blog), forKey: "blog")if let data = ud.objectForKey("blog") as? NSData {
    let unarc = NSKeyedUnarchiver(forReadingWithData: data)
    let newBlog = unarc.decodeObjectForKey("root") as Blog}


查看完整回答
反对 回复 2019-07-26
  • 3 回答
  • 0 关注
  • 1161 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信