iOS数据持久化 归档

归档(序列化),把对象转为字节码,以文件的形式存储到磁盘上;程序运行过程中或者当再次打开程序的时候,可以通过解归档(反序列化)还原这些对象。只要遵循了NSCoding协议的对象都可以通过它实现序列化,由于绝大多数支持存储数据的Foundation和Cocoa Touch类都遵循了NSCoding协议,因此,对于大多数类来说,归档相对而言还是比较容易实现的。

1.Foundation框架中单个对象的归档解档

  • 一次只能归档一个对象,如果是多个对象归档需要分开进行,归档和解档其中任意对象都需要归档和解档整个文件
  
  
  
  
  1. //获得沙盒路径
  2. NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
  3. //获取文件路径,由于归档后文件会加密,所以文件后缀可以任意取
  4. NSString *filePath = [documentPath stringByAppendingPathComponent:@"file.archiver"];
  5. //创建一个字典,用来归档
  6. NSDictionary *archiveDic = @{@"name":@"jack"};
  7. //调用NSKeyedArchiver的类方法archiveRootObject:toFile:将对象归档(返回一个布尔值)
  8. if([NSKeyedArchiver archiveRootObject:archiveDic toFile:filePath]){
  9. NSLog(@"archive success!");
  10. }
  11. //调用NSKeyedUnarchiver的类方法unarchiveObjectWithFile:将文件解档
  12. NSDictionary *unarchiveDic = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
  13. NSLog(@"%@", unarchiveDic);
  •  打印结果

02F77B90-3B4E-4D04-97E3-A0BE31A5565C

2.多个对象同时归档与解档

  • 多个对象可以同时归档,每个对象通过键值区分,解档时键值必须与归档时键值保持匹配归档和解档其中任意对象都需要归档和解档整个文件
  
  
  
  
  1. //获得沙盒路径
  2. NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
  3. //获取文件路径,由于归档后文件会加密,所以文件后缀可以任意取
  4. NSString *filePath = [documentPath stringByAppendingPathComponent:@"file.archiver"];
  5. //创建一个MutableData对象用于存放需要归档的数据
  6. NSMutableData *archiveData = [NSMutableData data];
  7. //创建一个NSKeyedArchiver类的对象archiver,用来对归档对象进行编码,编码完成才能进行归档
  8. NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:archiveData];
  9. [archiver encodeObject:@"jack" forKey:@"name"];
  10. [archiver encodeInt:20 forKey:@"age"];
  11. [archiver encodeFloat:72.5 forKey:@"weight"];
  12. //完成编码
  13. [archiver finishEncoding];
  14. //将archiveData对象写入文件,完成归档
  15. if ([archiveData writeToFile:filePath atomically:YES]) {
  16. NSLog(@"archive success!");
  17. }
  18. //创建NSData对象来接收解档文件
  19. NSData *unarchiveData = [NSData dataWithContentsOfFile:filePath];
  20. //创建一个NSKeyedUnarchiver对象unarchiver,用来对需要解档的对象进行解码,解码后就能还原原对象的数据类型
  21. NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:unarchiveData];
  22. NSString *name = [unarchiver decodeObjectForKey:@"name"];
  23. int age = [unarchiver decodeIntForKey:@"age"];
  24. float weight = [unarchiver decodeFloatForKey:@"weight"];
  25. NSLog(@"name = %@, age = %d, weight = %.2f", name, age, weight);
  • 打印结果:

3831015C-529B-461E-AE9A-2EE0D6EEAD69

3.自定义对象的归档

  • 自定义的对象归档需要实现NSCoding协议,并且实现协议中的方法,继承时必须先调用父类的归档解档方法,使用时可以直接调用普通Foundation框架中对象归档解档方法
  • 在项目中新建一个Person类,设置三个属性,遵守NSCoding协议并实现协议中的方法:
  
  
  
  
  1. @interface Person : NSObject <NSCoding>
  2. @property (copy, nonatomic) NSString *name;
  3. @property (copy, nonatomic) NSString *gender;
  4. @property (assign, nonatomic) int age;
  5. @end
  
  
  
  
  1. @implementation Person
  2.  
  3. //实现NSCoding协议中的归档方法
  4. - (void)encodeWithCoder:(NSCoder *)aCoder {
  5. [aCoder encodeObject:self.name forKey:@"name"];
  6. [aCoder encodeObject:self.gender forKey:@"gender"];
  7. [aCoder encodeInt:self.age forKey:@"age"];
  8. }
  9.  
  10. //实现NSCoding协议中的解档方法
  11. - (nullable instancetype)initWithCoder:(NSCoder *)aDecoder {
  12. if (self = [super init]) {
  13. self.name = [aDecoder decodeObjectForKey:@"name"];
  14. self.gender = [aDecoder decodeObjectForKey:@"gender"];
  15. self.age = [aDecoder decodeIntForKey:@"age"];
  16. }
  17. return self;
  18. }
  19. @end
  20.  
  •  对Person类创建出来的对象进行归档,归档方法同上文第一种方法一样
  
  
  
  
  1. //获得沙盒路径
  2. NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
  3. //获取文件路径,由于归档后文件会加密,所以文件后缀可以任意取
  4. NSString *filePath = [documentPath stringByAppendingPathComponent:@"file.archiver"];
  5. //自定义对象
  6. Person *person = [[Person alloc] init];
  7. person.name = @"jack";
  8. person.gender = @"male";
  9. person.age = 20;
  10. //归档
  11. if ([NSKeyedArchiver archiveRootObject:person toFile:filePath]) {
  12. NSLog(@"archive success!");
  13. }
  14. //解档,person2实例接收解档后的对象
  15. Person *person2 = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
  16. NSLog(@"name = %@, gender = %@, age = %d", person2.name, person2.gender, person2.age);

你可能感兴趣的:(ios,数据,存储)