数据持久化    参考1  参考2  参考3

什么是数据持久化,就是将文件保存在本地的硬盘中,使得应用程序或者机器重启后可以继续访问以前保留的数据。IOS开发中有许多的数据持久化方案。

如下面五种方案就是数据持久化方案。

plist(属性列表)
preference (偏好设置)
NSKeyedArchiver (归档)
SQLite3
CoreData
先看什么是“沙盒” 沙盒机制。 IOS程序默认的情况下只能访问程序自己的目录。这个目录被称为 “沙盒”。

沙盒的结构为:

既然沙盒就是一个文件夹,那就看看里面有什么吧。沙盒的目录结构如下:

应用程序包"
Documents
Library
    Caches
    Preferences
tmp
"应用程序包": 这里面存放的是应用程序的源文件,包括资源文件和可执行文件。

Documents: 最常用的目录,iTunes同步该应用时会同步此文件夹中的内容,适合存储重要数据。

Library/Caches: iTunes不会同步此文件夹,适合存储体积大,不需要备份的非重要数据。

Library/Preferences: iTunes同步该应用时会同步此文件夹中的内容,通常保存应用的设置信息。

tmp: iTunes不会同步此文件夹,系统可能在应用没运行时就删除该目录下的文件,所以此目录适合保存应用中的一些临时文件,用完就删除。

《什么是 iTunes,在本文最后附录》

Plist 文件:

plist文件是将某些特定的类,通过XML文件的方式保存在目录中。

可被序列化的类型只有如下几种:《什么是序列化——附录》

NSArray;
NSMutableArray;
NSDictionary;
NSMutableDictionary;
NSData;
NSMutableData;
NSString;
NSMutableString;
NSNumber;
NSDate;
只有以上可以被序列化的数据类型才可以使用plist 文件
存储时使用writeToFile: atomically:方法。 其中atomically表示是否需要先写入一个辅助文件,再把辅助文件拷贝到目标文件地址。这是更安全的写入文件方法,一般都写YES。
读取时使用arrayWithContentsOfFile:方法。
(单词:synchronize 使同步)(单词 Archiver 存储服务器)
使用方法:
//1.获得NSUserDefaults文件
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
//2.向文件中写入内容
[userDefaults setObject:@"AAA" forKey:@"a"];
[userDefaults setBool:YES forKey:@"sex"];
[userDefaults setInteger:21 forKey:@"age"];
//2.1立即同步
[userDefaults synchronize];
//3.读取文件
NSString *name = [userDefaults objectForKey:@"a"];
BOOL sex = [userDefaults boolForKey:@"sex"];
NSInteger age = [userDefaults integerForKey:@"age"];
NSLog(@"%@, %d, %ld", name, sex, age);

偏好设置是专门用来保存应用程序的配置信息的,一般不要在偏好设置中保存其他数据。

如果没有调用synchronize方法,系统会根据I/O情况不定时刻地保存到文件中。所以如果需要立即写入文件的就必须调用synchronize方法。

偏好设置会将所有数据保存到同一个文件中。即preference目录下的一个以此应用包名来命名的plist文件。

NSKeyedArchiver

归档在iOS中是另一种形式的序列化,只要遵循了NSCoding协议的对象都可以通过它实现序列化。由于决大多数支持存储数据的Foundation和Cocoa Touch类都遵循了NSCoding协议,因此,对于大多数类来说,归档相对而言还是比较容易实现的。

NSCoding 里有两个必须实现的协议。一个是说明如何将对象编码到归档中,另一个说明如何进行一个解档来获取一个新的对象。

遵循协议和设置属性:

//1.遵循NSCoding协议
  @interface Person : NSObject   //2.设置属性
  @property (strong, nonatomic) UIImage *avatar;
  @property (copy, nonatomic) NSString *name;
  @property (assign, nonatomic) NSInteger age;
  @end
实现协议的方法:

//解档
  - (id)initWithCoder:(NSCoder *)aDecoder {
      if ([super init]) {
          self.avatar = [aDecoder decodeObjectForKey:@"avatar"];
          self.name = [aDecoder decodeObjectForKey:@"name"];
          self.age = [aDecoder decodeIntegerForKey:@"age"];
      }
      return self;
  }
  //归档
  - (void)encodeWithCoder:(NSCoder *)aCoder {
      [aCoder encodeObject:self.avatar forKey:@"avatar"];
      [aCoder encodeObject:self.name forKey:@"name"];
      [aCoder encodeInteger:self.age forKey:@"age"];
  }
特别注意:

如果需要归档的类是某个自定义类的子类时,就需要在归档和解档之前先实现父类的归档和解档方法。即 [super encodeWithCoder:aCoder] 和 [super initWithCoder:aDecoder] 方法;

需要把对象归档是调用NSKeyedArchiver的工厂方法 archiveRootObject: toFile: 方法。

NSString *file = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject stringByAppendingPathComponent:@"person.data"];
  Person *person = [[Person alloc] init];
  person.avatar = self.avatarView.image;
  person.name = self.nameField.text;
  person.age = [self.ageField.text integerValue];
  [NSKeyedArchiver archiveRootObject:person toFile:file];
需要从文件中解档对象就调用NSKeyedUnarchiver的一个工厂方法 unarchiveObjectWithFile: 即可。

NSString *file = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject stringByAppendingPathComponent:@"person.data"];
  Person *person = [NSKeyedUnarchiver unarchiveObjectWithFile:file];
  if (person) {
     self.avatarView.image = person.avatar;
     self.nameField.text = person.name;
     self.ageField.text = [NSString stringWithFormat:@"%ld", person.age];
  }
注意

必须遵循并实现NSCoding协议

保存文件的扩展名可以任意指定

继承时必须先调用父类的归档解档方法

最新文章

  1. root与普通用户的切换
  2. NET微信公众号开发-5.0微信支付(待测试)
  3. php 封装mysql 数据库操作类
  4. atexit注册的函数是在main函数之后执行?
  5. VIM实用基本操作技巧
  6. Android 使用 HTTP 协议访问网络
  7. PKU 1458 Common Subsequence(最长公共子序列,dp,简单)
  8. jquery formValidate demo 采用struts 异步方式检验用户名是否存在
  9. MHA手动在线切换主 原创3(主不参与复制)
  10. javascript无缝全屏轮播
  11. Python学习笔记开篇
  12. CentOS(Linux)下安装dmidecode包
  13. 朴素贝叶斯分类法 Naive Bayes ---R
  14. Leetcode_136_Single Number
  15. Java中浮点数的精度问题 【转】
  16. RocketMQ生产消费模型选择
  17. 分页Sql语句
  18. Linux中重命名乱码文件
  19. Linux内核分析——第七章 链接
  20. Visitor模式和Observer观察者模式

热门文章

  1. 【英语】Bingo口语笔记(51) - 相信怀疑的表达
  2. SQL Server数据类型与SDE库表sde_type对照表
  3. 【PHP入门到精通】:Ch05:字符串处理
  4. C/C++中static关键字详解-zz
  5. HashBiMap
  6. effective java 笔记1--序言
  7. Selenium2Library系列 keywords 之 _SelectElementKeywords 之 select_from_list_by_label(self, locator, *labels)
  8. cmd命令 chcp
  9. HTML5_画布_太阳系
  10. Spring依赖注入 --- 模拟实现