Archiver是持久化数据的一种方式,他跟 Plist的差别在于他能持久化自己定义对象。但他没Plist那么方便。
Archiver默认能持久化的数据有NSNumber,NSArray,NSDictionary,NSString,NSData,由于这几个对象已经实现了
<NSCoding>协议。如果我们要实现一个对象的Archiver持久化 ,也必须实现该对象。
1.<NSCoding>协议主要为归档/恢复文件两个方法
//恢复归档文件为对象 -(id)initWithCoder:(NSCoder *)aDecoder //归档,使对象持久化 -(void)encodeWithCoder:(NSCoder *)aCoder
例如以下 。我们首先获取归档文件的路径
#pragma mark 获取文件路径 - (NSString *) filePath { NSArray *dirPaths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSAllDomainsMask, YES); NSString *dirPath=dirPaths[0]; NSString *filePath=[dirPath stringByAppendingPathComponent:@"aa.archiver"]; return filePath; }
2.系统默认对象怎样归档(NSNumber,NSArray,NSDictionary,NSString,NSData)
#pragma mark 归档/恢复 Array对象 - (void) savearray { NSString *filePath=[self filePath]; // // NSArray *arr=@[@"ttt",@"BBB",@25]; // [NSKeyedArchiver archiveRootObject:arr toFile:filePath]; // NSArray *arr1=[NSKeyedUnarchiver unarchiveObjectWithFile:filePath]; NSLog(@"%@",arr1); }
#pragma mark 归档/恢复 Dictionary对象 - (void) saveDic { NSString *filePath=[self filePath]; // NSDictionary *dict=@{@"name":@"lean",@"age":@25}; // BOOL flag=[NSKeyedArchiver archiveRootObject:dict toFile:filePath]; // NSLog(@"%d",flag); NSDictionary *dict2=[NSKeyedUnarchiver unarchiveObjectWithFile:filePath]; NSLog(@"%@",dict2); }
3.怎样归档自己定义对象。
定义了一个Person类。例如以下:
#import <Foundation/Foundation.h> @interface Person : NSObject <NSCoding> @property (nonatomic,copy) NSString *name; @property (nonatomic,assign) int age; + (Person *) initWithName:(NSString *)name andAge:(int) age; @end #import "Person.h" @implementation Person + (Person *) initWithName:(NSString *)name andAge:(int) age { Person *p=[[Person alloc] init]; p.name=name; p.age=age; return p; } -(void)encodeWithCoder:(NSCoder *)aCoder { [aCoder encodeObject:self.name forKey:@"name"]; [aCoder encodeInt:self.age forKey:@"age"]; } -(id)initWithCoder:(NSCoder *)aDecoder { [self setName:[aDecoder decodeObjectForKey:@"name"]]; [self setAge:[aDecoder decodeIntForKey:@"age"]]; return self; } @endTIP: 无论是encode还是decode 都是依据对象的类型去选用不同的方法。如
encodeInt:forkey: encodeDouble:forkey: encodeFloat:forkey:
decodeObjectForKey: decodeIntForKey: decodeDoubleForKey:
NSKeyedArchiver archiveRootObject:toFile:
NSKeyedUnarchiver unarchiveObjectWithFile:
各自是对须要归档。
恢复的对象进行操作的两个类
定义完了Person类后,在须要归档的地方调用例如以下:
#pragma mark 归档/恢复 自己定义对象 - (void) savePerson { NSString *filePath=[self filePath]; Person *p=[Person initWithName:@"lean" andAge:22]; BOOL flag=[NSKeyedArchiver archiveRootObject:p toFile:filePath]; Person *p2=[NSKeyedUnarchiver unarchiveObjectWithFile:filePath]; NSLog(@"%d-%d",flag,p2.age); }
对于其Person类,如果该类中还有自己定义对象作为属性。相同实现<NSCoding>协议
4.如果该对象是某个对象子类,这里我们建立一个叫Student类作为Person的子类
#import "Person.h" @interface Student : Person @property (nonatomic ,assign) int no; + (Student *) initWithName:(NSString *)name andAge:(int) age andNO:(int) no; @end
相同Student也须要实现NSCoding协议的方法
-(id)initWithCoder:(NSCoder *)aDecoder { if (self=[super initWithCoder:aDecoder]) { [self setNo:[aDecoder decodeIntForKey:@"no"]]; } return self; } -(void)encodeWithCoder:(NSCoder *)aCoder { [super encodeWithCoder:aCoder]; [aCoder encodeInt:self.no forKey:@"no"]; }
#pragma mark 归档/恢复 自己定义子类对象 - (void) saveStudent { NSString *filePath=[self filePath]; Student *p=[Student initWithName:@"lean" andAge:22 andNO:150133]; BOOL flag=[NSKeyedArchiver archiveRootObject:p toFile:filePath]; Student *p2=[NSKeyedUnarchiver unarchiveObjectWithFile:filePath]; NSLog(@"%d-%@",flag,p2.name); }