当前位置: 代码迷 >> 综合 >> iOS 12对象序列化(NSKeyedArchiver)
  详细解决方案

iOS 12对象序列化(NSKeyedArchiver)

热度:7   发布时间:2024-02-06 11:37:08.0

NSKeyedArchiver对象序列化

    • NSKeyedArchiver归档
    • NSKeyedArchiver解档

自iOS 12以后对象序列化的方法有了些许变化,用以记录

NSKeyedArchiver归档

由原来的

+ (BOOL)archiveRootObject:(id)rootObject toFile:(NSString *)path

变为

+ (nullable NSData *)archivedDataWithRootObject:(id)object requiringSecureCoding:(BOOL)requiresSecureCoding error:(NSError **)error- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile

后面一个是我搭配使用的,你换一个也无所谓,甚至你可以将数据存到NSUserDefualt中也可以。

举个栗子

#import "WuluFMSHCTBusiness.h"NS_ASSUME_NONNULL_BEGIN@interface WuluFMSHCTBusinesses : NSObject/// 全局数据
@property (nonatomic, strong) NSArray<WuluFMSHCTBusiness *>    *ctBusinesses;/// ctBusinessList生成时间戳,yyyymmddhh24miss
@property (nonatomic, copy) NSString                            *ctTimeStamp;/// 单例类,数据全局通用
+ (instancetype)shareInstance;/// 字典转模型
/// @param modelDict 模型字典
+ (instancetype)modelWithDictionary:(NSDictionary *)modelDict;@endNS_ASSUME_NONNULL_END

在.m文件中实现协议NSCoding协议

序列化define的数据后面需要追加代码

\
+ (BOOL)supportsSecureCoding { \return YES; \
}

使用以下代码进行归档

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);NSString *documentFilePath = paths.firstObject;NSString *filePath = [documentFilePath stringByAppendingPathComponent:CTBusinessesKey];NSError *error = nil;NSData *archiveData = [NSKeyedArchiver archivedDataWithRootObject:ctBusinesses requiringSecureCoding:YES error:&error];if (archiveData == nil || error) {NSLog(@"归档失败:%@", error);return NO;}BOOL isSuccess = [archiveData writeToFile:filePath atomically:YES];return isSuccess;

出现过的错误

Error Domain=NSCocoaErrorDomain Code=4864 "This decoder will only decode classes that adopt NSSecureCoding. Class '对象' does not adopt it." UserInfo={NSDebugDescription=This decoder will only decode classes that adopt NSSecureCoding. Class '对象' does not adopt it.}

原因
在需要归档的对象头上需要添加NSSecureCoding协议

@interface WuluFMSHCTBusinesses : NSObject<NSSecureCoding>

NSKeyedArchiver解档

也由原来的

+ (nullable id)unarchiveObjectWithFile:(NSString *)path

变为

+ (nullable id)unarchivedObjectOfClass:(Class)cls fromData:(NSData *)data error:(NSError **)error

但是当我使用以下代码进行解档时却报错了

WuluFMSHCTBusinesses *ctBusinesses = [NSKeyedUnarchiver unarchivedObjectOfClasses:[WuluFMSHCTBusinesses class] fromData:archiveData error:&error];

错误

Error Domain=NSCocoaErrorDomain Code=4864 "value for key 'ctBusinesses' was of unexpected class 'NSArray'. Allowed classes are '对象'." UserInfo={NSDebugDescription=value for key 'title' was of unexpected class 'NSArray'. Allowed classes are '对象'.}

意思是什么呢?

对象不符合!!!

解决办法,当你对象中包含对象、数组等数据时,将你的对象全部声明出来,不管嵌套多少个,有多少个对象声明多少。

NSData *archiveData = [NSData dataWithContentsOfFile:filePath];
NSSet *classSet = [NSSet setWithObjects:[NSArray class], [NSMutableArray class], [WuluFMSHCTBusinesses class], [WuluFMSHCTBusiness class], [WuluFMSHCommonInfo class], [WuluFMSHIssueBN class], [WuluFMSHTopupBN class], [WuluFMSHRefundBN class], [WuluFMSHPayChannel class], nil];WuluFMSHCTBusinesses *ctBusinesses = [NSKeyedUnarchiver unarchivedObjectOfClasses:classSet fromData:archiveData error:&error];

至此方休
参考