归档:3-自定义对象归档/解档
当我们需要存储的数据类型是一些基本的数据类型时,例如:NSString、NSArray、NSDictionary,我们可以使用Plist文件来直接进行存储。但是当我们需要存储自定义对象时,使用Plist文件就变得不方便了,这时推荐使用归档来存储自定义对象。存储自定义对象在iOS开发中的使用是非常普遍的。
NSCoding协议
可以归档的对象在定义时都需要遵守NSCoding协议,并且实现协议中定义的归档、解档方法,如下所示。由于我们常用的基本数据类型,如NSString、NSArray、NSDictionary,苹果官方在定义时已经默认遵守了该协议并且实现了归档、解档方法,所以我们可以直接对基本数据类型进行归档解档操作,而自定义对象则需要手工实现。
- NSCoding协议中的对象归档方法
- (void)encodeWithCoder:(NSCoder *)aCoder;
- NSCoding协议中的对象解档方法
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder;
自定义对象归档/解档的主要步骤
当我们需要对自定义对象进行归档和解档时,通常需要按照如下步骤进行:
- 新建自定义类,并遵守NSCoding协议;
- 实现NSCoding协议中用于归档解档的方法;
- 创建自定义对象,并使用NSKeyedArchiver以及NSKeyedUnarchiver类中的方法进行对象的归档与解档
示例代码
我们通过一个示例,介绍一下自定义对象归档与解档的方法。
- 新建自定义Person类,并遵守NSCoding协议,在Person.h文件中,添加两个属性以及一个类方法
@interface Person : NSObject<NSCoding>
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSNumber *age;
+(instancetype)personWithDict:(NSDictionary *) dict;
@end
- 在Person.m文件中,实现encodeWithCoder:以及initWithCoder:方法
//实现NSCoding协议中的归档方法
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:self.name forKey:@"name"];
[aCoder encodeObject:self.age forKey:@"age"];
}
//实现NSCoding协议中的解档方法
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder {
if (self = [super init]) {
self.name = [aDecoder decodeObjectForKey:@"name"];
self.age = [aDecoder decodeObjectForKey:@"age"];
}
return self;
}
- 新建ArchiveService工具类,在ArchiveService.h文件中添加如下两个方法,用于对象的归档、解档操作
#import <Foundation/Foundation.h>
#import "Person.h"
@interface ArchiveService : NSObject
+ (BOOL) writeObjectToArchiveFile:(Person *) object;
+ (Person *) readObjectFromArchiveFile;
@end
- 在ArchiveService.m文件中实现用于归档的方法
+ (BOOL) writeObjectToArchiveFile:(Person *) object {
//获取文件路径
NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSString *filePath = [docPath stringByAppendingPathComponent:@"person.archive"];
//调用NSKeyedArchiver的类方法archiveRootObject:toFile:将对象归档(返回一个布尔值)
return [NSKeyedArchiver archiveRootObject:object toFile:filePath];
}
- 在ArchiveService.m文件中实现用于解档的方法
+ (Person *) readObjectFromArchiveFile {
//获取文件路径
NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSString *filePath = [docPath stringByAppendingPathComponent:@"person.archive"];
//调用NSKeyedUnarchiver的类方法unarchiveObjectWithFile:将文件解档
Person *person = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
return person;
}
- 使用Storyboard搭建一个界面,能够输入name以及age,并且添加两个按钮【写入归档文件】、【读取归档文件】,并与控制器类建立连线;
- 实现【写入归档文件】按钮点击功能
- (IBAction)writeToArchive:(id)sender {
NSDictionary *dict = @{@"name":self.nameTextField.text,
@"age":self.ageTextField.text};
Person *person = [Person personWithDict:dict];
if([ArchiveService writeObjectToArchiveFile:person]){
NSLog(@"归档成功");
};
}
- 实现【读取归档文件】按钮点击功能
- (IBAction)readFromArchiive:(id)sender {
Person *person = [ArchiveService readObjectFromArchiveFile];
NSLog(@"person name: %@, person age:%@", person.name,person.age);
}
- 运行后,输入name以及age的取值,点击【写入归档文件】,可以看到界面如下提示,并且在App的沙盒文件夹中新增person.archive文件
- 点击【读取归档文件】按钮,可以从归档文件中读取存储的自定义对象,并打印出结果。
https://github.com/99ios/13.4.3
文章发布时间为: December 5th , 2016 at 04:45 pm
最后编辑时间为: September 15th , 2017 at 05:33 am
本文由 99ios 创作,转载请注明出处
最后编辑时间为: September 15th , 2017 at 05:33 am
本文由 99ios 创作,转载请注明出处