当前位置: 首页 > news >正文

使用序列化和反序列化函数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,转NSStringNSError *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

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

http://www.lryc.cn/news/95792.html

相关文章:

  • python获取鼠标出颜色
  • Github Flow工作流简单介绍(以部署为中心的开发模式)
  • selenium浏览器驱动下载
  • go学习 模块与包 - Init函数 - 如何导入第三方包 - 切片与数组的数据传递方式 - go中文件的读写
  • 2023第五届全国生物资源提取与应用创新论坛即将举办
  • Socks5代理在爬虫与HTTP应用中的重要性
  • 二叉树详解
  • Git的核心概念:探索Git中的提交、分支、合并、标签等核心概念,深入理解其作用和使用方法
  • JAVA设计模式——23种设计模式详解
  • Oracle输出文本平面(CSV、XML)文本数据详细过程
  • 基于C++的QT基础教程学习笔记
  • 【数据分享】全国地级市1999—2020年工业企业数(Shp/Excel格式)
  • 设计模式【行为型】-- 责任链模式
  • [Spring] 三级缓存解决循环依赖详解
  • gerrit 从安装到出坑
  • Java工程师就业前景怎么样?能拿多少工资?
  • 极速跳板机登陆服务器
  • 【算法与数据结构】226、LeetCode翻转二叉树
  • metaRTC6.0 new feature (一)
  • 聊天机器人如何增加电子商务销售额
  • stm32 IIC通信
  • Elasticsearch监控工具Cerebro安装
  • RTOS 低功耗设计原理及实现
  • PaddleOCR C++编译出错解决方案
  • 89、简述RabbitMQ的架构设计
  • 63 | 图像处理
  • Stable Diffusion - 扩展 Roop 换脸 (Face Swapping) 插件的配置与使用
  • opencv实现替换证件照颜色
  • Elasticsearch【全文检索、倒排索引、应用场景、对比Solr、数据结构】(一)-全面详解(学习总结---从入门到深化)
  • 了解 3DS MAX 3D摄像机跟踪设置:第 2 部分