方法中加上一句必威,应用必须待在自己的沙盒

ZDCar *car = [[ZDCar alloc] init]; car.brand = @"BMW"; car.color = @"black"; //获取caches文件夹 NSString *cachesPath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0]; //拼接文件名 NSString *filePath = [cachesPath stringByAppendingPathComponent:@"car.xxoo"]; //存储数据 [NSKeyedArchiver archiveRootObject:car toFile:filePath];

- 归档存储的读取

//获取caches文件夹 NSString *cachesPath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0]; //拼接文件名 NSString *filePath = [cachesPath stringByAppendingPathComponent:@"car.xxoo"]; //读取数据 ZDCar *car = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
[self performSegueWithIdentifier:@"jumpToContact" sender:nil];
把一些系统自带的OC对象生成pilst文件存储起来。
  • 1> 了解数据存储:数据存储一般有两个操作,一个存,一个取。拖两个按钮,一个用来存,一个用来取
  • 2> plist存储原理:
    • 只要有writeToFile的对象,就能进行plist存储,调用writeToFile就能自动生成plist格式的文件。
    • 一般常用的Foundation对象都有这个方法,数组,字典,字符串等
  • 3> 如何写入到沙盒,需要获取沙盒路径。
    • 获取Documents路径
    • 拼接文件名,因为数据是写入到文件中,不是写入到文件夹中。路径之间通过/分开的,为了避免自己写/,会用stringByAppendingPathCompent,自动在文件夹与文件之间添加/。
  • 4> 如何读取,存储是什么类型存储,读取出来也是什么类型,直接用存储的类型,解析文件就好,用ContentsOfFile解析。
  • 5> 注意plist存储,不能存储自定义对象,会失败的。

在person.m

一、iOS应用数据存储的常用方式

  • 1、XML属性列表(plist)归档
  • 2、Preference(偏好设置)
  • 3、NSKeyedArchiver归档(NSCoding) // 所谓归档,是一个过程,即用某种格式来保存一个或者多个对象,以便以后还原这些对象
  • 4、SQLite3
  • 5、Core Data
 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; [defaults setObject:@"jack" forKey:@"name"]; [defaults setInteger:26 forKey:@"age"];

- 偏好设置读取

NSString *name = [[NSUserDefaults standardUserDefaults] objectForKey:@"name"]; NSInteger age = [[NSUserDefaults standardUserDefaults] integerForKey:@"age"];

关闭控制器

2、plist存储

13> 偏好设置

二、数据存储

1、 pist文件读与写

  • 特点:只能存储OC常用数据类型(NSString、NSDictionary、NSArray、NSData、NSNumber等类型)而不能直接存储自定义模型对象

    • 如果想存储自定义模型对象 -> 只能将自定义模型对象转换为字典存储;
  • 1.1 使用须知:

    • 前提条件:一个对象必须实现了writeToFile方法,因为我们是通过调用对象的writeToFile方法将对象写入到一个plist文件中的
     // 将数组写入plist文件:(系统提供的类实现的writeToFile方法)
     [array writeToFile:filePath atomically:YES];
    
    • plist只能识别字典,数组
  • 1.2 读写数据 - > 实例代码

   NSString *docPath =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES)[0];
    // 拼接要保存的地方的路径
    NSString *filePath = [docPathstringByAppendingPathComponent:@"str.plist"];
    // 1、写入数据
    [array writeToFile:filePath atomically:YES];
    // 2、 读取数据
    NSArray *array = [NSArray arrayWithContentsOfFile:filePath];

**​2、偏好设置: **

  • 每个应用都有个NSUserDefaults实例,通过它来存取偏好设置,比如,保存用户名、字体大小、是否自动登录

  • 2.1 好处:

    • 1.存储数据不需要关心文件名称
    • 2.快速存储键值对
  • 2.2 底层实现:

    • 它其实就是一个字典
  • 2.3 用途: 账户或者密码,开关状态

  • 2.4 注意:设置数据时,synchornize方法强制写入

    • UserDefaults设置数据时,不是立即写入,而是根据时间戳定时地把缓存中的数据写入本地磁盘。所以调用了set方法之后数据有可能还没有写入磁盘应用程序就终止了。出现以上问题,可以通过调用synchornize方法强制写入
  • 2.5 基本使用

    NSUserDefaults *UserDefaults = [NSUserDefaultsstandardUserDefaults];
    // 1、写入
    [UserDefaults setBool:NO forKey:@"isLogined"];
    // 强制写入
    [defaults synchornize];  

    // 2、读取
    BOOL isVisble = [UserDefaults boolForKey:@"isLogined"];

3、获取临时文件夹路径

//    3.1 获取临时文件夹路径
    NSString *tmp = NSTemporaryDirectory();
//    3.2 定义宏,快速访问临时文件夹中文件
#define FilePath [NSTemporaryDirectory() stringByAppendingPathComponent:@"person.data"]

4、归档 NSKeyedArchiver

  • 特点:

      1. 可以存储自定义模型对象
      • NSKeyedArchiver归档相对较plist存储而言,它可以直接存储自定义模型对象,而plist文件需要将模型转为字典才可以存储自定义对象模型;
    • 2.归档不能存储大批量数据(相比较Sqlite而言),存储数据到文件是将所有的数据一下子存储到文件中,从文件中读取数据也是一下子读取所有的数据;

  • 缺点:

    • 假如你的文件中有100个对象了,然后你想在利用归档添加一个对象,你需要先把所有的数据解档出来,然后再加入你想添加的那个对象,同理,你想删除一个文件中的一个对象也是,需要解档出所有的对象,然后将其删除。性能低这样处理
  • 4.1 基本使用:需要归档的模型类必须要遵守NSCoding协议,然后模型实现类中必须实现两个方法:1>encodeWithCoder -> 归档;2> initWithCoder: - > 解档

  • 4.2 使用注意:

    • 如果父类也遵守了NSCoding协议,请注意:

应该在encodeWithCoder:方法中加上一句

[super encodeWithCode:encode]; // 确保继承的实例变量也能被编码,即也能被归档

应该在initWithCoder:方法中加上一句

self = [super initWithCoder:decoder]; // 确保继承的实例变量也能被解码,即也能被恢复

+ 基本使用

```objc
// 1. 自定义模型类Person

// 1.1 Person.h文件
#import <Foundation/Foundation.h>

// 只要一个自定义对象想要归档,必须要遵守NSCoding协议,并且要实现协议的方法
@interface Person : NSObject<NSCoding>

@property (nonatomic, assign) int age;

@property (nonatomic, strong) NSString *name;

@end

// 1.2 .m实现文件
#import "Person.h"

#define KName @"name"
#define KAge @"age"

@implementation Person

// 什么时候调用:当一个对象要归档的时候就会调用这个方法归档
// 作用:告诉苹果当前对象中哪些属性需要归档
- (void)encodeWithCoder:(NSCoder *)aCoder
{
 [aCoder encodeObject:_name forKey:KName];
 [aCoder encodeInt:_age forKey:KAge];
}

// 什么时候调用:当一个对象要解档的时候就会调用这个方法解档
// 作用:告诉苹果当前对象中哪些属性需要解档
// initWithCoder什么时候调用:只要解析一个文件的时候就会调用
- (id)initWithCoder:(NSCoder *)aDecoder
{
 #warning  [super initWithCoder]
 if (self = [super init]) {
     // 解档
     // 注意一定要记得给成员属性赋值
   _name = [aDecoder decodeObjectForKey:KName];
   _age = [aDecoder decodeIntForKey:KAge];
 }
 return self;
}

@end

// 2. 实例 -》基本使用:取 / 存 数据 
// 归档
[NSKeyedArchiver archiveRootObject: self.persons toFile:KFilePath];// 将self.persons模型对象数组 

// 解档       
_persons = [NSKeyedUnarchiver unarchiveObjectWithFile:KFilePath];

5、SQLite3

  • 它是一款开源的嵌入式关系型数据库,可移植性好、易使用、内存开销小
  • 特点:可以存储大量数据
  • 详情,请参见 【SQLite3篇】

6、Core Data

  • Core Data框架提供了对象-关系映射(ORM)的功能
    • 即能够将OC对象转化成数据,保存在SQLite3数据库文件中,也能够将保存在数据库中的数据还原成OC对象。
  • 在此数据操作期间,不需要编写任何SQL语句
  • 使用此功能,要添加CoreData.framework和导入主头文件<CoreData/CoreData.h>
  • 详情,请参见【Core Data篇】
 NSArray *array = @[@"jack",@26]; //获取caches文件夹路径 //NSSearchPathDirectory directory -->搜索文件夹 //NSSearchPathDomainMask domainMask -->在哪个范围内查找 //BOOL expandTilde -->是否展开 NSString *cachesPath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0]; //拼接文件名 NSString *filePath = [cachesPath stringByAppendingPathComponent:@"array.plist"]; //存储数据 [array writeToFile:filePath atomically:YES];

- plist存储的数据读取(比如想要读取一个数组)

 //获取caches文件夹路径 NSString *cachesPath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0]; //拼接文件名 NSString *filePath = [cachesPath stringByAppendingPathComponent:@"array.plist"]; //读取文件 NSArray *array = [NSArray arrayWithContentsOfFile:filePath];
  • Modal

  • 效果:默认是新控制器从屏幕的最底部往上钻,直到盖住之前的控制器为止

4、自定义对象归档(归档:数据存储)

  • 1> 自定义对象如何归档:用NSKeyedArchiver,调用archiveRootObject:toFile:方法,需要传一个对象,自定义一个对象,传进去。
  • 会报错,说对象没有encodeWithCoder方法,说明归档的时候默认会调用这个方法,去实现这个方法。
  • 默认打不出encodeWithCoder,必须遵守NSCoding协议才能实现这个方法。
  • encodeWithCoder什么时候调用:对象归档时候调用
  • encodeWithCoder作用:告诉系统对象里的哪些属性需要归档,怎么去归档,根据一个key去归档,目的就是以后取的时候,也根据这个key去取数据。
  • 2> 自定义对象如何解档:用NSKeyedUnarchiver,调用unarchiveObjectWithFile方法,需要传一个文件名。
  • 会报错,说对象没有initWithCoder方法,说明解档的时候默认会调用这个方法,去实现这个方法。
  • initWithCoder什么时候调用:对象解档时候调用
  • initWithCoder作用:告诉系统对象里的哪些属性需要解档,怎么去解档,根据之前存储的key去解档
  • initWithCoder是一个初始化方法,需要先初始化父类的,但是不能调用[super initWithCoder:],因为父类NSObject没有遵守NSCoding协议。
  • 3> initWithCoder什么时候需要调用[super initWithCoder:]
  • initWithCoder原理:只要解析文件就会调用,xib,storyboard都是文件,因此只要解析这两个文件,就会调用initWithCoder。
  • 因此如果在storyboard使用自定义view,重写initWithCoder方法,一定要调用[super initWithCoder:],因为只有系统才知道怎么解析storyboard,如果没有调用,就解析不了这个文件。

NSString *filePath = [cachePath stringByAppendingPathComponent:@"arr.plist"];

- (void)dismissViewControllerAnimated: (BOOL)flag completion: (void (^)(void))completion;

1、数据存储(数据持久化)

  • 1> 介绍iOS数据存储的5种方式
  • 2> 介绍应用沙盒(应用程序的文件夹)
  • 如何找到应用沙盒的路径?首先需要显示隐藏文件。
  • 点击前往->个人->资源库->Application Support->iPhone Simulator->7.1->里面全是应用沙盒
  • 3> 应用沙盒怎么多文件夹保存,在哪个文件夹。介绍沙盒里的每一个文件夹。

很多iOS应用都支持偏好设置,比如保存用户名、密码、字体大小等设置,iOS提供了一套标准的解决方案来为应用加入偏好设置功能

注意:在调用[NSKeyedArchiver archiveRootObject:car toFile:filePath];和[NSKeyedUnarchiver unarchiveObjectWithFile:filePath];这两个方法时底层会调用- encodeWithCoder:(NSCoder *)aCoder- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder这两个方法 所以需要在自定义的类中遵守<NSCoding>这个协议并实现上述两个方法还有一点需要注意 在实现- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder这个方法时当父类遵守了<NSCoding>这个协议就需要调用[super initWithCoder:aDecoder] 反之则调用[super init]

plist 数据存储

  • Plist注意:不能存储自定义对象
  • Plist:数组和字典
  • 如何判断一个对象能不能使用Plist,就看下有没有writeToFile
    NSArray *arr = @[@"1234",@1];

    // 获取应用的文件夹(应用沙盒)
    //    NSString *homePath = NSHomeDirectory();

    // 获取temp
    //    NSTemporaryDirectory();

    // 获取Cache文件路径
    // NSSearchPathDirectory:搜索的目录
    // NSSearchPathDomainMask:搜索范围 NSUserDomainMask:表示在用户的手机上查找
    // expandTilde 是否展开全路径,如果没有展开,应用的沙盒路径就是~
    // 存储一定要要展开路径
    NSString *cachePaht = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0];

    // 拼接文件名
    NSString *filePath = [cachePaht stringByAppendingPathComponent:@"personArr.plist"];

    // File:文件的全路径
    [arr writeToFile:filePath atomically:YES];


    // 文件读取
    NSArray *array = [NSArray arrayWithContentsOfFile:filePath];
  • 完成写入

必威 1

写入效果图

4、偏好设置

  • 很多iOS应用都支持偏好设置,比如保存用户名、密码、字体大小等设置,iOS提供了一套标准的解决方案来为应用加入偏好设置功能
  • 每个应用都有个NSUserDefaults实例,通过它来存取偏好设置
    比如,保存用户名、字体大小、是否自动登录.
  • 以字典的形式进行偏好设置,用法跟字典一样.
  • 偏好设置好处:
  • 1.不需要关心文件名
  • 2.快速进行键值对存储
  • 3.直接存储基本数据类型
保存:
    // 获取单例
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    // @"123" key:pwd
    [defaults setObject:@"123" forKey:@"pwd"];

    // bool
    [defaults setBool:YES forKey:@"isOn"];

    // int
    [defaults setInteger:10 forKey:@"num"];

读取:
    // 利用NSUserDefaults单例
   NSString *pwd = [[NSUserDefaults standardUserDefaults] objectForKey:@"pwd"];
   NSInteger i = [[NSUserDefaults standardUserDefaults] integerForKey:@"num"];

// 将字典持久化到Documents/stu.plist文件中

  • 归档存储 --任何对象都可以进行归档存储 自定义对象也可以``NSKeyedArchiver专门用来做自定义对象归档
    • 归档存储(比如想要存储一个自定义对象car)

3、应用沙盒目录的常见获取方式

// 获取沙盒路径

  • 1、NSHomeDirectory()

  • 2、tmp:NSString *tmp = NSTemporaryDirectory();

  • 3、Library/Caches:(跟Documents类似的2种方法)
    利用沙盒根目录拼接”Caches”字符串
    利用NSSearchPathForDirectoriesInDomains函数(将函数的参数改为:NSCachesDirectory即可)

    // directory:获取哪个文件夹
    // domainMask:在哪个范围内搜索,NSUserDomainMask:表示在用户的手机上查找
    // expandTilde:是否展开全路径 YES:表示展开全路径 NO:不会展开全路径,会把应用沙盒的路径用波浪号(~)代替
    // 获取到Caches文件夹路径
    NSString *cachePath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0];

    // 拼接文件名
    NSString *filePath = [cachePath stringByAppendingPathComponent:@"arr.plist"];

    // 1、存储plist,File:文件的全路径
    [arr writeToFile:filePath atomically:YES];
    // 2、读取plist,之前是什么类型存储的,读取也是什么
    NSArray *arr = [NSArray arrayWithContentsOfFile:filePath];
  • 4、Library/Preference:通过NSUserDefaults类存取该目录下的设置信息
    //  写入
    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    //    [userDefaults setBool:NO forKey:@"jhyes"];
    //    [userDefaults setObject:@"ljh" forKey:@"name"];
    [userDefaults setValue:@"JHL" forKey:@"NAME"];
    // 数据持久化
    [userDefaults synchronize];

    // 9 读取
    NSUserDefaults *redDef = [NSUserDefaults standardUserDefaults];
    //    BOOL result = [redDef boolForKey:@"jhyes"];
    //    NSString *result = [redDef objectForKey:@"name"];
    NSString *result = [redDef valueForKey:@"NAME"];
    NSLog(@"result = %@", result);
}

NSLog(@"person2:0x%x", person2); // person2:0x7177cf0

总结

存储自定义对象

在iOS开发中常常需要将本地数据存储起来 通常有如下几种方式

/** 取出 storyboard 中 ID 为"edit"的控制器*/
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
XBEditViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"edit"];

/** 向控制器传递数据 */
vc.contact = self.contacts[indexPath.row];
vc.block = ^{
    [self.tableView reloadData];
};

/** 压栈跳转控制器 */
[self.navigationController pushViewController:vc animated:YES];

2、应用沙盒结构分析

  • 应用程序包:(上图中的Layer)包含了所有的资源文件和可执行文件

  • Documents:保存应用运行时生成的需要持久化的数据,iTunes同步设备时会备份该目录。例如,游戏应用可将游戏存档保存在该目录

  • tmp:保存应用运行时所需的临时数据,使用完毕后再将相应的文件从该目录删除。应用没有运行时,系统也可能会清除该目录下的文件。iTunes同步设备时不会备份该目录

  • Library/Caches:保存应用运行时生成的需要持久化的数据,iTunes同步设备时不会备份该目录。一般存储体积大、不需要备份的非重要数据

  • Library/Preference:保存应用的所有偏好设置,iOS的Settings(设置)应用会在该目录中查找应用的设置信息。iTunes同步设备时会备份该目录

归档:

- (void)presentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^)(void))completion

6、NSData

  • 使用archiveRootObject:toFile:方法可以将一个对象直接写入到一个文件中,但有时候可能想将多个对象写入到同一个文件中,那么就要使用NSData来进行归档对象
  • NSData可以为一些数据提供临时存储空间,以便随后写入文件,或者存放从磁盘读取的文件内容。可以使用[NSMutableData data]创建可变数据空间
1)NSData-归档2个Person对象到同一文件中

归档(编码)

// 新建一块可变数据区
NSMutableData *data = [NSMutableData data];
// 将数据区连接到一个NSKeyedArchiver对象
NSKeyedArchiver *archiver = [[[NSKeyedArchiver alloc] initForWritingWithMutableData:data] autorelease];
// 开始存档对象,存档的数据都会存储到NSMutableData中
[archiver encodeObject:person1 forKey:@"person1"];
[archiver encodeObject:person2 forKey:@"person2"];
// 存档完毕(一定要调用这个方法)
[archiver finishEncoding];
// 将存档的数据写入文件
[data writeToFile:path atomically:YES];

2)NSData-从同一文件中恢复2个Person对象

恢复(解码)

// 从文件中读取数据
NSData *data = [NSData dataWithContentsOfFile:path];
// 根据数据,解析成一个NSKeyedUnarchiver对象
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
Person *person1 = [unarchiver decodeObjectForKey:@"person1"];
Person *person2 = [unarchiver decodeObjectForKey:@"person2"];
// 恢复完毕
[unarchiver finishDecoding];

3)利用归档实现深复制
比如对一个Person对象进行深复制

// 临时存储person1的数据
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:person1];
// 解析data,生成一个新的Person对象
Student *person2 = [NSKeyedUnarchiver unarchiveObjectWithData:data];
// 分别打印内存地址
NSLog(@"person1:0x%x", person1); // person1:0x7177a60
NSLog(@"person2:0x%x", person2); // person2:0x7177cf0



归档:
存储自定义对象

    Person *p = [[Person alloc] init];
    p.age = 18;
    p.name = @"a";
    // 获取tem文件夹路径
    NSString *tempPath = NSTemporaryDirectory();
    // 拼接文件名
   NSString *filePath = [tempPath stringByAppendingPathComponent:@"person.data"];
    // NSKeyedArchiver专门用来做自定义对象归档
    [NSKeyedArchiver archiveRootObject:p toFile:filePath];



在person.m

// 什么时候调用:当一个对象要归档的时候就会调用这个方法归档
// 作用:告诉苹果当前对象中哪些属性需要归档
- (void)encodeWithCoder:(NSCoder *)aCoder
{
    [aCoder encodeObject:_name forKey:@"name"];
    [aCoder encodeInt:_age forKey:@"age"];
}

解档:

    // 获取tem文件夹路径
    NSString *tempPath = NSTemporaryDirectory();

    // 拼接文件名
    NSString *filePath = [tempPath stringByAppendingPathComponent:@"person.data"];
   // 解档
   Person *p = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];


什么时候调用:当一个对象要解档的时候就会调用这个方法解档

// 作用:告诉苹果当前对象中哪些属性需要解档
// initWithCoder什么时候调用:只要解析一个文件的时候就会调用
- (id)initWithCoder:(NSCoder *)aDecoder
{
    #warning  [super initWithCoder]
    // 这里不能用[super initWithCoder],什么时候调用[super initWithCoder:aDecoder]:只要父类遵守了NSCoding协议,就调用
    if (self = [super init]) {
        // 解档
        // 注意一定要记得给成员属性赋值
      _name = [aDecoder decodeObjectForKey:@"name"];
      _age = [aDecoder decodeIntForKey:@"age"];
    }
    return self;
}

• 会报错,说对象没有encodeWithCoder方法,说明归档的时候默认会调用这个方法,去实现这个方法。

  • plist存储
  • 偏好设置存储
  • 归档存储
  • SQLite存储
  • core data存储今天简单介绍一下前面三种存储方式
    • plist存储 --plist存储的本质就是生成一个plist文件 是用来存储数组和字典,但是需要注意的是自定义对象不能用plist来进行存储plist是什么类型存储的 读取也必须是同样的类型
    • plist存储的存储数据(比如想要存储一个数组)

加载新控制器

3、偏好设置

  • 1> 什么是偏好设置存储:就是保存一些基本的信息,账号,密码,状态。
  • 2> 偏好设置原理:不需要关心文件名,直接通过NSUserDefaults操作,默认就存到偏好设置里面了。
    • 通过NSUserDefaults就能直接访问软件的偏好设置(Library/Preferences)
  • 3> 怎么利用偏好设置存储?利用NSUserDefaults调用setObject:forKey存储。
    • 偏好设置底层实现原理:底层其实就是利用一个字典,存储一些键值对。
    • 偏好设置好处:能快速存储一些键值对,如果用字典去存储,还需要获取文件名比较麻烦。
    • 偏好设置坏处:不能及时存储,需要做同步操作,把内存中的数据同步到硬盘上。
  • 4> 怎么利用偏好设置读取?和字典一样,根据刚刚存储的Key读取。

(图)

  • 偏好设置存储 --偏好设置存储是以字典的形式进行偏好设置,用法跟字典一样 偏好设置存储主要用到一个关键类NSUserDefaults``偏好设置存储的好处:不需要关心文件名 可以快速进行键值对存储 可以存储基本数据类型
    • 偏好设置存储

NO.1前言

Person *person2 = [unarchiver decodeObjectForKey:@"person2"];

  • 连线跳转方式,根据绑定的 ID 进行控制器跳转

NO2.操做

1> 什么是偏好设置存储:就是保存一些基本的信息,账号,密码,状态。

  • 代码方式跳转

5、属性列表

  • 1 plist存储,生成一个plist文件.
  • 2 plist不是数组就是字典,plist存储就是用来存储字典或者数组.
    注意:Plist不能存储自定义对象
  • 3 属性列表是一种XML格式的文件,拓展名为plist
  • 4 如果对象是NSString、NSDictionary、NSArray、NSData、NSNumber等类型,就可以使用writeToFile:atomically:方法直接将对象写到属性列表文件中
// 写入:
// 将一个NSDictionary对象归档到一个plist属性列表
// 将数据封装成字典
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject:@"coderLee" forKey:@"name"];
[dict setObject:@"13903058421" forKey:@"phone"];
[dict setObject:@"27" forKey:@"age"];
// 将字典持久化到Documents/stu.plist文件中
[dict writeToFile:path atomically:YES];

// 读取:
// 读取属性列表,恢复NSDictionary对象
[dict dictionaryWithContentsOfFile:path];

[archiver encodeObject:person1 forKey:@"person1"];

偏好设置存储

  • 偏好设置存储好处:
    1 不需要关心文件名
    2 快速做键值对存储

  • 底层:就是封装了一个字典

NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]
    ;

    [userDefaults setObject:@"sxb" forKey:@"account"];
    [userDefaults setObject:@"123" forKey:@"password"];
    [userDefaults setBool:YES forKey:@"rmbPwd"];

    // 在iOS7之前,默认不会马上把跟硬盘同步
    // 手动同步
//    [userDefaults synchronize];
  • 读取
    NSString *pwd = [[NSUserDefaults standardUserDefaults] objectForKey:@" password"];

1、应用沙盒

  • 每个iOS应用都有自己的应用沙盒(应用沙盒就是文件系统目录),与其他文件系统隔离。应用必须待在自己的沙盒里,其他应用不能访问该沙盒
  • 应用沙盒的文件系统目录,如下图所示(假设应用的名称叫Layer)
  • 模拟器应用沙盒的根路径在: (apple是用户名, 8.0是模拟器版本)
    /Users/apple/Library/Application Support/iPhone Simulator/8.0/Applications

Person *p = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];

  • 然后系统会调用

1、iOS应用数据存储的常用方式

  • XML属性列表(plist)归档
  • Preference(偏好设置)
  • NSKeyedArchiver归档(NSCoding)
  • SQLite3 <数据库>
  • Core Data

// 拼接文件名

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender

模拟器应用沙盒的根路径在: (apple是用户名, 8.0是模拟器版本)

向下一个控制器顺序传递数据,可以在此方法中编写

// initWithCoder什么时候调用:只要解析一个文件的时候就会调用

自定义对象的归档

  • 归档可以存储自己定义的对象
Person *p = [[Person alloc] init];
    p.age = 18;

    // 获取cache
    NSString *cachePath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0];

    // 获取文件的全路径
    NSString *filePath = [cachePath stringByAppendingPathComponent:@"person.data"];

    // 把自定义对象归档
    [NSKeyedArchiver archiveRootObject:p toFile:filePath];

    // 解档
    Person *p = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
  • 同时 如果一个自定义对象想要归档,必须遵守NSCoding协议
    @interface Person : NSObject<NSCoding>
  • 并且实现协议,描述归档和解档的属性
@implementation Person

// 什么时候调用:自定义对象归档的时候

// 作用:用来描述当前对象里面的哪些属性需要归档
- (void)encodeWithCoder:(NSCoder *)aCoder
{
    // name
    [aCoder encodeObject:_name forKey:@"name"];

    // age
    [aCoder encodeInt:_age forKey:@"age"];

}


// 什么时候调用:解档对象的时候调用

// 作用:用来描述当前对象里面的哪些属性需要解档
// initWithCoder:就是用来解析文件的。
- (id)initWithCoder:(NSCoder *)aDecoder
{
    // super:NSObject

    if (self = [super init]) {

        // 注意:一定要给成员变量赋值
        // name
       _name = [aDecoder decodeObjectForKey:@"name"];

        // age
       _age = [aDecoder decodeIntForKey:@"age"];

    }
    return self;

}

NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];

每个iOS应用都有自己的应用沙盒(应用沙盒就是文件系统目录),与其他文件系统隔离。应用必须待在自己的沙盒里,其他应用不能访问该沙盒

// 将存档的数据写入文件

// 解档

6、属性列表

// 解析data,生成一个新的Person对象

Person *person1 = [unarchiver decodeObjectForKey:@"person1"];

什么时候调用:当一个对象要解档的时候就会调用这个方法解档

// 将数据封装成字典

2> plist存储原理:

[defaults setInteger:10 forKey:@"num"];

1、NSHomeDirectory()

if (self = [super init]) {

• initWithCoder作用:告诉系统对象里的哪些属性需要解档,怎么去解档,根据之前存储的key去解档

// 恢复完毕

1> 了解数据存储:数据存储一般有两个操作,一个存,一个取。拖两个按钮,一个用来存,一个用来取

4、Library/Preference:通过NSUserDefaults类存取该目录下的设置信息

NSString *filePath = [tempPath stringByAppendingPathComponent:@"person.data"];

• initWithCoder原理:只要解析文件就会调用,xib,storyboard都是文件,因此只要解析这两个文件,就会调用initWithCoder。

- (void)encodeWithCoder:(NSCoder *)aCoder

// 2、读取plist,之前是什么类型存储的,读取也是什么

应用沙盒的文件系统目录,如下图所示(假设应用的名称叫Layer)

本文由必威发布于必威-编程,转载请注明出处:方法中加上一句必威,应用必须待在自己的沙盒

TAG标签:
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。