加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ios – 在NSUserDefaults中存储自定义对象时,应用程序崩溃

发布时间:2020-12-14 19:24:30 所属栏目:百科 来源:网络整理
导读:我有名为User的自定义类符合NSCoding协议.但是当我试图将它存储在NSUserDefaults中时,我收到此错误: Property list invalid for format: 200 (property lists cannot contain objects of type 'CFType') 这个警告: NSForwarding: warning: object 0x7f816a
我有名为User的自定义类符合NSCoding协议.但是当我试图将它存储在NSUserDefaults中时,我收到此错误:

Property list invalid for format: 200 
(property lists cannot contain objects of type 'CFType')

这个警告:

NSForwarding: warning: object 0x7f816a681110 of class 'Shikimori.User'
does not implement methodSignatureForSelector: -- trouble ahead
Unrecognized selector -[Shikimori.User _copyDescription]

用户类:

class User: NSCoding {

private enum CoderKeys: String {
    case ID = "user.id"
    case Username = "user.username"
    case Email = "user.email"
    case Avatar = "user.avatar"
}

let id: Int
let username: String
let email: String
let avatar: String

init(id: Int,username: String,email: String,avatar: String) {
    self.id = id
    self.username = username
    self.email = email
    self.avatar = avatar
}

required init(coder aDecoder: NSCoder) {
    id = aDecoder.decodeIntegerForKey(CoderKeys.ID.rawValue)
    username = aDecoder.decodeObjectForKey(CoderKeys.Username.rawValue) as String
    email = aDecoder.decodeObjectForKey(CoderKeys.Email.rawValue) as String
    avatar = aDecoder.decodeObjectForKey(CoderKeys.Avatar.rawValue) as String
}

func encodeWithCoder(aCoder: NSCoder) {
    aCoder.encodeInteger(id,forKey: CoderKeys.ID.rawValue)
    aCoder.encodeObject(username as NSString,forKey: CoderKeys.Username.rawValue)
    aCoder.encodeObject(email as NSString,forKey: CoderKeys.Email.rawValue)
    aCoder.encodeObject(avatar as NSString,forKey: CoderKeys.Avatar.rawValue)
}
}

更新
保存代码:

let userKeyForDefaults = "apimanager.user"


let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject(user,forKey: self.userKeyForDefaults)

解决方法

NSUserDefaults不支持所有对象,例如NSString,NSDictionary,最重要的是NSData.这就是NSCoding协议派上用场的地方.它允许我们将自定义对象转换为NSData的块.为此,请使用NSKeyedArchiver类将符合NSCoding的自定义对象转换为等效的NSData

let obj = User()
let data = NSKeyedArchiver. archivedDataWithRootObject(obj)
/// Now you can store data

可以找到文档here,您正在寻找的方法是

class func archivedDataWithRootObject(_ rootObject: AnyObject) -> NSData

要从NSUserDefaults中获取信息,请使用“反向”类NSKeyedUnarchiver.其适当的方法如下

class func unarchiveObjectWithData(_ data: NSData) -> AnyObject?

这是一个例子.

let data = NSUserDefaults.standardUserDefaults().objectForKey("somekey")
let obj = NSKeyedUnarchiver. unarchiveObjectWithData(data) as User?

注意:我可能混淆了一些选项,但你得到了jist. NSKeyedUnarchiver的文档可以在here找到.

编辑:修复OP的问题就像正确使用NSKeyedArchiver和子类化NSObject一样简单.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读