猿问

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

使用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。谢谢。


MMMHUHU
浏览 1169回答 3
3回答

动漫人物

第一个问题是你必须确保你有一个非破坏的类名:@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)}

森林海

在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) {}

ABOUTYOU

正如@ 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}
随时随地看视频慕课网APP
我要回答