使用序列化和反序列化函数archivedDataWithRootObject和unarchivedObjectOfClasses的使用和遇到问题及解决方案

这篇具有很好参考价值的文章主要介绍了使用序列化和反序列化函数archivedDataWithRootObject和unarchivedObjectOfClasses的使用和遇到问题及解决方案。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

为何archiveRootObject和unarchiveObjectWithFile正常,而archivedDataWithRootObject和unarchivedObjectOfClasses一直报错。
[NSKeyedArchiver archiveRootObject:account toFile:path];和`c
PPAccountModel *account = [NSKeyedUnarchiver unarchiveObjectWithFile:path];


```c
'archiveRootObject:toFile:' is deprecated: first deprecated in iOS 12.0 - Use +archivedDataWithRootObject:requiringSecureCoding:error: and -writeToURL:options:error: instead
'unarchiveObjectWithFile:' is deprecated: first deprecated in iOS 12.0 - Use +unarchivedObjectOfClass:fromData:error: instead

替换很简单,但是会一堆问题等着你解决,序列化和反序列全失败。
先说能简单解决的序列化(归档):

    NSString *path = [self PathWithFileName:@"啊啊啊.data"];//拓展名可以自己随便取
    DYGlobleData.token = @"";
    PPAccountModel *account = nil;
//    [NSKeyedArchiver archiveRootObject:account toFile:path];
    NSError *error = nil;
    NSData *archiveData = [NSKeyedArchiver archivedDataWithRootObject:account requiringSecureCoding:YES error:&error];
    if (archiveData == nil || error) {
        NSLog(@"归档失败:%@", error);
    }
    BOOL isSuccess = [archiveData writeToFile:path atomically:YES];
    if(!isSuccess)
    {
        NSLog(@"归档存储失败:%d", isSuccess);
    }

简单吧!也不是很复杂。首先失败的提示信息如下:

Error Domain=NSCocoaErrorDomain Code=4866 "未能写入数据,因为它的格式不正确。" UserInfo={NSUnderlyingError=0x2835675a0 {Error Domain=NSCocoaErrorDomain Code=4864 "This decoder will only decode classes that adopt NSSecureCoding. Class 'PPAccountModel' does not adopt it." UserInfo={NSDebugDescription=This decoder will only decode classes that adopt NSSecureCoding. Class 'PPAccountModel' does not adopt it.}}}

这是啥鬼?搞了半天查出来了,是序列化时采用了requiringSecureCoding为YES。但是序列化的类采用的是NSCoding协议,可以设置成NO,这样能序列化成功,但是反序列化就不能保证怎么样了。那就遵循NSSecureCoding协议吧!改造也很简单,在头文件换成NSSecureCoding,在实现文件写上supportsSecureCoding函数具体代码:

@interface PPAccountModel : NSObject<NSCoding>
+ (BOOL)supportsSecureCoding {
    return YES;
}

遇到空数组序列化失败:

[aCoder encodeObject:[NSMutableArray array] forKey:@"usersAvatar"];

修改为:

    if(isCommonUnitEmptyArray(self.usersAvatar))
    {
        [aCoder encodeObject:@"" forKey:@"usersAvatar"];
    }
    else
    {
        [aCoder encodeObject:self.usersAvatar forKey:@"usersAvatar"];
    }

也很简单啊!序列化搞定。
反序列化坑更多。序列化成功但是反序列化错误:
反序列化:

//得到用户信息
-(PPAccountModel *)getAccountInfo;
{
    FLDDLogDebug(@"函数");
    NSString *path = [self PathWithFileName:@"啊啊啊.data"];//拓展名可以自己随便取
//    PPAccountModel *account = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
    // NSData转array,转dictionary,转NSString
    NSError *err = nil;
    NSData *archiveData = [NSData dataWithContentsOfFile:path];
    if(!archiveData)
    {
        return nil;
    }
    PPAccountModel *account = [NSKeyedUnarchiver unarchivedObjectOfClasses:[NSSet setWithArray:@[NSArray.class,NSDictionary.class, NSString.class, UIFont.class, NSMutableArray.class, NSMutableDictionary.class, NSMutableString.class, UIColor.class, NSMutableData.class, NSData.class, NSNull.class, NSValue.class,NSDate.class, XQUserModel.class, NSNumber.class, PPAccountModel.class, XQTimeMapModel.class]] fromData:archiveData error:&err];
    _account = account;
    if (archiveData == nil || err) {
        NSLog(@"反序列化失败:%@", err);
    }
//    if((account == nil) || (kUserLogin))
    NSLog(@"account = %@",account);
    if(account == nil)
    {
//        [[NSUserDefaults standardUserDefaults] setBool:NO forKey:kLoginStateKey];
//        [[NSUserDefaults standardUserDefaults] removeObjectForKey:kLoginToken];
//        [[NSUserDefaults standardUserDefaults] synchronize];
        self.isLogin = NO;
        DYGlobleData.token = @"";
        [BITSingleObject sharedInstance].token = @"";
    }
    else
    {
        self.isLogin = YES;
        [BITSingleObject sharedInstance].token = account.token;
        DYGlobleData.token = account.token;
        [account fetchRoleData];
    }
   
    return account;
}

首先保证把参与序列化的所有对象类型都列举出来,写少了就4865 错误。但是全部列举万了还是4865错误,错误信息如下:

object c  -[NSKeyedUnarchiver decodeObjectForKey:]:    missing class information for object

到处查资料也没有查到解决方案,我试了半天我快放弃了,才找到原因。因为序列化的用户信息是反序列化后给单例对象了,这个用户信息增加了一些不需要序列化的成员变量,把它当用户相关的单例成员变量了,没有实现序列化和反序列化。我把这些变量去掉或序列化就反序列化正常了。
注意:子类的序列化和反序列化时需要把父类的变量也序列化和反序列化。文章来源地址https://www.toymoban.com/news/detail-600193.html

到了这里,关于使用序列化和反序列化函数archivedDataWithRootObject和unarchivedObjectOfClasses的使用和遇到问题及解决方案的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Unity-序列化和反序列化

    序列化是指把对象转换为字节序列的过程,而反序列化是指把字节序列恢复为对象的过程。序列化最主要的用途就是传递对象和保存对象。 在Unity中保存和加载、prefab、scene、Inspector窗口、实例化预制体等都使用了序列化与反序列化。 1 自定义的具有Serializable特性的非抽象、

    2024年01月24日
    浏览(56)
  • 【Linux】序列化和反序列化

    在网络编程中,直接使用 结构体 进行数据传输会出错,因为 本质上socket无法传输结构体 ,我们只有将结构体装换为字节数组,或者是字符串格式来传输,然后对端主机收到了数据,再将其转化为结构体,这就是序列化和反序列化的过程! 序列化 (Serialization)是将对象的状态

    2024年02月10日
    浏览(42)
  • Java序列化和反序列化

    目录 一、序列化和反序列化 二、Java序列化演示 三、反序列化漏洞 1、含义 ​序列化就是内存中的对象写入到IO流中,保存的格式可以是二进制或者文本内容。反序列化就是IO流还原成对象。 2、用途 (1)传输网络对象 (2)保存Session 1、序列化 java.io.ObjectOutputStream代表对象

    2023年04月25日
    浏览(38)
  • 什么是序列化和反序列化?

    JSON(JavaScript Object Notation)和XML(eXtensible Markup Language)是两种常用的数据交换格式,用于在不同系统之间传输和存储数据。 JSON是一种轻量级的数据交换格式,它使用易于理解的键值对的形式表示数据。JSON数据结构简单明了,易于读写和解析,是基于JavaScript的一种常用数据

    2024年02月09日
    浏览(57)
  • Java序列化和反序列化机制

    在阅读 ArrayList 源码的时候,注意到,其内部的成员变量动态数组 elementData 被Java中的 transient 修饰 transient 意味着Java在序列化时会跳过该字段(不序列化该字段) 而Java在默认情况下会序列化类(实现了 Java.io.Serializable 接口的类)的所有非瞬态(未被 transient 修饰

    2024年03月15日
    浏览(50)
  • TCP定制协议,序列化和反序列化

    目录 前言 1.理解协议 2.网络版本计算器 2.1设计思路 2.2接口设计 2.3代码实现: 2.4编译测试 总结         在之前的文章中,我们说TCP是面向字节流的,但是可能对于面向字节流这个概念,其实并不理解的,今天我们要介绍的是如何理解TCP是面向字节流的,通过编码的方式,自

    2024年02月12日
    浏览(34)
  • [计算机网络]---序列化和反序列化

    前言 作者 :小蜗牛向前冲 名言 :我可以接受失败,但我不能接受放弃    如果觉的博主的文章还不错的话,还请 点赞,收藏,关注👀支持博主。如果发现有问题的地方欢迎❀大家在评论区指正  目录  一、再谈协议 二、序列化和反序化 1、网络版本计算器的场景搭建 2、

    2024年02月20日
    浏览(43)
  • java中的序列化和反序列化

    objectOutputStream 对象的序列化,以流的形式将对象写入文件 构造方法: objectOutputStream(OutputStream out) 传入一个字节输入流创建objectOutputStream对象 成员方法: void writeObject(object obj) 将指定的对象写入objectOutputStream 使用步骤: 创建一个类,这个类实现Serializable接口,Serializable是一

    2024年02月14日
    浏览(35)
  • jackjson自定义序列化和反序列化

    JRT引用的jackjson作为json处理库。由于JRT.ORM要求表不用datetime类型,把日期和时间用Int存储,所以ORM要支持日期时间的转换。为什么要把日期时间不用datetime而用Int,比如日期:20240117,时间就是从0点到当前的秒数。因为不用datetime兼容性好,不会因为不同库datetime函数不同而要

    2024年01月18日
    浏览(39)
  • Java中序列化和反序列化解释

    在Java中,序列化(Serialization)是指将对象的状态转换为字节流的过程,以便将其保存到文件、在网络中传输或持久化到数据库中。而反序列化(Deserialization)则是将字节流转换回对象的过程,恢复对象的状态。 序列化和反序列化主要用于以下场景: 1. 对象持久化:通过序列

    2024年02月07日
    浏览(56)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包