IOS持久化之NSKeyedArchiver,NSKeyedUnarchiver
来源:互联网 发布:海岛奇兵21本升级数据 编辑:程序博客网 时间:2024/05/16 07:33
归档与反归档需要NSCoding协议的支持, 需要编解码的自定义对象的类也要支持该协议。
NSCoding协议:
- (void) encodeWithCoder : (NSCoder *) aCoder;
- (id) initWithCoder:(NSCoder *) aDecoder;
NSKeyedArchiver,NSKeyedUnarchiver类支持NSCoder协议:
- (void)encodeObject:(nullableid)objv forKey:(NSString *)key;
- (nullableid)decodeObjectForKey:(NSString *)key;
协议支持示例代码(user,childUser,teacher属性分别为类User,ChildUser,Teacher的对象,User,ChildUser和Teacher类均实现了NSCoding协议):
其中,如果encodeObject:forKey和deCodeObjectForKey的对象如果是自定义的类的话,则该自定义类也要实现NSCoding协议来支持对其编解码,如果是NSObject等类对象的话,这些类本身支持了编解码(NSObject支持编解码,但是不支持NSCoding协议,因此基类是NSObject不能调用基类的编解码方法)。encodeWithCode和initWithCoder方法中的归档与反归档的对象必须成对出现,否则持久化就会出错。注意这个方法中,如果父类也支持NSCoding协议,一般会调用基类的encodeWithCoder和initWithCoder方法。
<p class="p1"><span class="s1">- (</span><span class="s2">void</span><span class="s1">)encodeWithCoder:(</span><span class="s3">NSCoder</span><span class="s1"> *)aCoder{</span></p><p class="p2"><span class="s1"> </span><span class="s4" style="font-family: Menlo;"> [aCoder </span><span class="s1" style="font-family: Menlo;">encodeObject</span><span class="s4" style="font-family: Menlo;">:</span><span class="s1" style="font-family: Menlo;">_user</span><span class="s4" style="font-family: Menlo;"> </span><span class="s1" style="font-family: Menlo;">forKey</span><span class="s4" style="font-family: Menlo;">:</span><span class="s5" style="font-family: Menlo;">@"user"</span><span class="s4" style="font-family: Menlo;">];</span></p><p class="p3"><span class="s4"> [aCoder </span><span class="s1">encodeObject</span><span class="s4">:</span><span class="s1">_childUser</span><span class="s4"> </span><span class="s1">forKey</span><span class="s4">:</span><span class="s5">@"childUser"</span><span class="s4">];</span></p><p class="p3"><span class="s4"> [aCoder </span><span class="s1">encodeObject</span><span class="s4">:</span><span class="s1">_teacher</span><span class="s4"> </span><span class="s1">forKey</span><span class="s4">:</span><span class="s5">@"teacher"</span><span class="s4">];</span></p><p class="p1"><span class="s1">}</span></p><p class="p2"><span class="s1"></span></p><p class="p1"><span class="s1">- (</span><span class="s2">id</span><span class="s1">)initWithCoder:(</span><span class="s3">NSCoder</span><span class="s1"> *)aDecoder{</span></p><p class="p3"><span class="s4"> </span><span class="s1">_user</span><span class="s4"> = [ aDecoder </span><span class="s1">decodeObjectForKey</span><span class="s4">:</span><span class="s5">@"user"</span><span class="s4">];</span></p><p class="p3"><span class="s4"> </span><span class="s1">_childUser</span><span class="s4"> = [ aDecoder </span><span class="s1">decodeObjectForKey</span><span class="s4">:</span><span class="s5">@"childUser"</span><span class="s4">];</span></p><p class="p3"><span class="s4"> </span><span class="s1">_teacher</span><span class="s4"> = [aDecoder </span><span class="s1">decodeObjectForKey</span><span class="s4">:</span><span class="s5">@"teacher"</span><span class="s4">];</span></p><p class="p4"><span class="s4"> </span><span class="s1">return</span><span class="s4"> </span><span class="s1">self</span><span class="s4">;</span></p><p class="p1"><span class="s1">}</span></p>
ChildUser方法中的NSCoding协议支持如下,由于调用了super::encodeWithCoder,因此基类和派生类编辑码的键名不可以重名,如果重名,归档的话,后面的会覆盖前面的:
- (void)encodeWithCoder:(NSCoder *)aCoder{ [super encodeWithCoder:aCoder]; [aCoder encodeObject:_name2 forKey:@"name"]; return;}- (id)initWithCoder:(NSCoder *)aDecoder{ self = [super initWithCoder:aDecoder]; _name2 = [ aDecoder decodeObjectForKey:@"name"]; return self;}
调用方法:
// 测试NSKeyedArchiver键名重名
UserGroup *userGroup = [[UserGroupalloc] init];
NSArray *pathArray =NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask, YES);
NSString *fileDirectory = [pathArrayobjectAtIndex:0];
NSString *filePath = [fileDirectorystringByAppendingPathComponent:@"test.txt"];
//归档
BOOL bSuccess = [NSKeyedArchiverarchiveRootObject:userGroup toFile: filePath];
//反归档
UserGroup *userGroup2 = [NSKeyedUnarchiverunarchiveObjectWithFile:filePath];
开始测试时归档失败,是因为NSSearchPathForDirectoriesInDomains第二个参数设置为了NSLocalDomainMask,这个参数得到的目录,不是沙盒内部,没有写权限。
NSMutableData *tempData = [NSMutableData data]; NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:tempData]; [archiver encodeObject:userGroup forKey:@"root"]; <span style="font-family: Consolas, 'Courier New', Courier, mono, serif; line-height: 18px; background-color: rgb(248, 248, 248);">//可以编、解码多个</span>[archiver finishEncoding]; if (![tempData writeToFile:dataFilePath atomically:YES]) { NSLog(@"fail to archive data object"); }
NSData *tempData = [NSData dataWithContentsOfFile:dataFilePath]; if (tempData) { // 通过解码恢复对象 NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:tempData]; UserGroup userGroup = <span style="margin: 0px; padding: 0px; border: none; font-family: Consolas, 'Courier New', Courier, mono, serif; line-height: 18px; background-color: rgb(248, 248, 248);">[unarchiver decodeObjectForKey: @"root"</span><span style="margin: 0px; padding: 0px; border: none; font-family: Consolas, 'Courier New', Courier, mono, serif; line-height: 18px; background-color: rgb(248, 248, 248);">]; //可以编、解码多个</span> [unarchiver finishDecoding];
上述通过NSData方式操作数据可以实现深复制,如下:
NSData *tempData = [NSKeyedArchiver archivedDataWithRootObject:marray1]; marray2 = [NSKeyedUnarchiver unarchiveObjectWithData:tempData];
userGroup归档后的文件内容如下:
bplist00‘89T$topX$objectsX$versionY$archiver—TrootÄ≠#$%+.3U$null‘TuserWteacherV$classYchildUserÄÄÄÄ“TnameÄÄ“X$classesZ$classname¢TUserXNSObjectTUser” !"YchildNameÄÄÄUuser2ZChilduser2“&*£'()YChildUserTUserXNSObjectYChildUser“,-ÄÄ“/2¢01WTeacherXNSObjectWTeacher“47¢56YUserGroupXNSObjectYUserGroup܆_NSKeyedArchiver(25:<JPY^fmwy{}Ñâãçíõ¶©Æ∑º√Õœ—”Ÿ‰È̘¸ (19>AKT^c:u键名用的明文,键值和对象的类的信息经过了处理,具体结构不详。
NSKeyedArchiverDelegate, NSKeyedUnarchiverDelegate,归档和反归档代理,可以设置NSKeyedArchive和NSKeyedUnarchiver对象的delegate属性,当归档和反归档时可以根据数据情况增加一些特殊处理。
- IOS持久化之NSKeyedArchiver,NSKeyedUnarchiver
- ios开发学习笔记--数据持久化之归档解档(NSKeyedArchiver/ NSKeyedUnarchiver)
- NSKeyedArchiver、NSKeyedUnarchiver 数据持久化归档
- IOS数据持久化之NSKeyedArchiver
- IOS数据持久化之归档NSKeyedArchiver
- iOS数据持久化之NSKeyedArchiver(归档)
- iOS数据持久化之归档NSKeyedArchiver
- ios:NSKeyedArchiver/NSKeyedUnarchiver(归档/解档)
- ios数据存储之--对模型对象归档(NSKeyedArchiver、NSKeyedUnarchiver)
- ios数据存储之--对模型对象归档(NSKeyedArchiver、NSKeyedUnarchiver)
- ios数据存储之--对模型对象归档(NSKeyedArchiver、NSKeyedUnarchiver)
- ios数据存储之--模型对象归档(NSKeyedArchiver、NSKeyedUnarchiver)
- iOS开发之归档(NSKeyedArchiver)和反归档(NSKeyedUnarchiver)
- iPhone开发【二十二】数据持久化总结之第3篇—归档(NSKeyedArchiver、NSKeyedUnarchiver)
- iPhone开发【二十二】数据持久化总结之第3篇—归档(NSKeyedArchiver、NSKeyedUnarchiver)
- 数据持久化之NSKeyedArchiver
- 数据持久化之NSKeyedArchiver
- iOS开发------本地存储-NSKeyedArchiver & NSKeyedUnarchiver(归档)
- C# string.split 分割字符串
- launch文件remap标签
- 数学建模常用算法
- #Objective - C - sixth-Day 数组排序及集合遍历
- 深度估计软件DERS5.1软件与配置运行详细步骤
- IOS持久化之NSKeyedArchiver,NSKeyedUnarchiver
- 1223第三十五节
- CALayer简单应用——带阴影的icon
- listview中如何通过selector改变点击时的背景色
- Java Day2
- 05.(java基础)-02final,finally,finalize的区别
- AFNetWorking使用总结(待总结。。。)
- Objective-C代码混淆
- hdu 2602 Bone Collector(01背包)(水)