IOS三种归档(NSKeyArchieve)的总结
IOS三种归档(NSKeyArchieve)的总结
归档是一种IOS中常用来存储文件的一种方法,在面向对象的语言中,归档也就实际上可以将一切对象存储在文件中,以下是IOS开发中常见的三种文件归档方式,分别是简单归档、data归档、自定义归档。现分别总结如下:
简单归档是指把简单的字符串、数组等对象进行归档。用到的方法是archiveRootObject,语句为 [NSKeyedArchiver archiveRootObject:array toFile:path];
其中红色的array是我们要归档的数组,path是要把array归档到的文件,也就是说我们需要先有这个array,以及先创建好path。
Array的创建(在实际使用中通常是已经对已经有的东西进行归档,所以不需要创建):NSArray *array = @[@"1",@"2",@"3"];
Path:path是沙盒中的文件,所以我们先要在沙盒中创建这么一个文件,但是在归档的语句中会自动根据路径和文件名创建这个文件,所以我们只需要先定义出一个文件路径,语句是:
NSString *path = [NSString stringWithFormat:@"%@/Documents/myfile.mp3",NSHomeDirectory()];
通过这种方式归档的对象,可以通过NSKeyedUnarchiver去解归档
归档过程和解归档的完整的代码如下:
// 初始化需要归档的数组 NSArray *array = @[@"1",@"2",@"3"]; // 创建归档文件的路径 NSString *path = [NSString stringWithFormat:@"%@/Documents/myfile.mp3",NSHomeDirectory()]; // 归档 [NSKeyedArchiver archiveRootObject:array toFile:path]; // 解归档 NSArray *array1 = [NSKeyedUnarchiver unarchiveObjectWithFile:path]; // 打印 NSLog(@"%@",array1);
这种归档方式是先新建一个可变的data对象,然后通过创建一个NSKeyedArchiver实例对象对各种类型的数据进行归档到data的归档文件中,归档方法为
encodeObject: forKey:这样的方法。具体的操作过程见以下代码:
1 // data归档 2 3 // 创建一个文件路径 4 NSString *pathdata = [NSString stringWithFormat:@"%@/Documents/a.mp3",NSHomeDirectory()]; 5 6 // 创建一个可变data 7 NSMutableData *datanow = [[NSMutableData alloc]init]; 8 9 // 创建一个归档实例,路径为之前创建的文件路径 10 NSKeyedArchiver *keyarch = [[NSKeyedArchiver alloc]initForWritingWithMutableData:datanow]; 11 12 // 归档 13 [keyarch encodeObject:@"hahha" forKey:@"one"]; 14 [keyarch encodeInteger:133 forKey:@"two"]; 15 [keyarch finishEncoding]; 16 17 18 [datanow writeToFile:pathdata atomically:YES]; 19 20 21 22 // 解归档 23 NSData *dataout = [NSData dataWithContentsOfFile:pathdata]; 24 25 NSKeyedUnarchiver *unarch = [[NSKeyedUnarchiver alloc]initForReadingWithData:dataout]; 26 27 NSString *stringone = [unarch decodeObjectForKey:@"one"]; 28 NSInteger x = [unarch decodeIntegerForKey:@"two"]; 29 NSLog(@"%@,%ld",stringone,(long)x);
如果某一个对象有多个属性值,那么我们如果对这些值分别进行归档的话,会很麻烦,而且要使用这些数据的话,解归档的过程也会很麻烦,最好的办法就是把整个对象的属性变量归档到一个对象的归档文件中,然后解归档的时候也是整个对象一起解归档,然后想用什么属性值就可以直接使用了。
这样我们就要先定义一个类User,这个类首先要遵守NSCoding协议,这个类有两个属性,分别是name和age。以下是.h文件:
1 // User.h 2 #import <Foundation/Foundation.h> 3 4 //遵守NSCoding协议 5 @interface User : NSObject<NSCoding> 6 //定义属性name和age 7 @property(nonatomic,strong)NSString *name; 8 @property(nonatomic,strong)NSString *age; 9 10 @end
然后在.m文件中重写一个归档方法,一个解归档方法,以及一个description方法:
1 // User.m 2 3 #import "User.h" 4 5 @implementation User 6 7 //重写归档方法,把调用者的属性进行归档 8 -(void)encodeWithCoder:(NSCoder *)aCoder 9 { 10 [aCoder encodeObject:self.age forKey:@"age"]; 11 [aCoder encodeObject:self.name forKey:@"name"]; 12 } 13 14 //重写解归档方法,把属性赋值给新对象的对应属性 15 -(instancetype)initWithCoder:(NSCoder *)aDecoder 16 { 17 self = [super init]; 18 if (self) { 19 self.age = [aDecoder decodeObjectForKey:@"age"]; 20 self.name = [aDecoder decodeObjectForKey:@"name"]; 21 } 22 return self; 23 } 24 25 //重写description方法,打印对象时可直接调用此函数 26 - (NSString *)description 27 { 28 return [NSString stringWithFormat:@"%@ %@", self.name,self.age]; 29 } 30 31 @end
以上description方法重写之后,当使用NSLog方法打印User对象时,就会直接调用此方法,也就是会打印self.name,self.age。
1 - (void)viewDidLoad { 2 [super viewDidLoad]; 3 4 代码; 5 }
然后在以上的代码位置处写入代码段:
1 // 初始化对象 2 User *myUser = [[User alloc]init]; 3 myUser.age = @"234"; 4 myUser.name = @"bearapp.me"; 5 6 7 // 定义归档文件路径 8 NSString *pathdata = [NSString stringWithFormat:@"%@/Documents/myUser.mp3",NSHomeDirectory()]; 9 10 11 // 调用对象的归档方法 12 [NSKeyedArchiver archiveRootObject:myUser toFile:pathdata]; 13 14 // 调用解归档方法 15 User *userout = [NSKeyedUnarchiver unarchiveObjectWithFile:pathdata]; 16 NSLog(@"%@",userout);
以上代码段创建了一个User对象,并使用点语法给这个对象的两个属性赋值,赋值完成后,定义了一个归档路径文件,并使用NSKeyedArchiver把这个对象归档到归档文件中。这样就完成了整个对象的归档。
通过NSKeyedUnarchiver调用unarchiveObjectWithFile:pathdata方法可以完成对应pathdata的解归档,并赋值给一个对象,然后打印整个对象。
由于我们重写了description 方法,所以在使用NSLog()方法打印对象时会分别打印对象的两个属性,打印输出如下:
2016-04-13 14:28:17.195 自定义归档[44181:2130618] bearapp.me 234