iOS开发笔记(十三):持久化方案之 plist 归档

本文详细介绍了iOS系统的沙盒机制,解释了沙盒目录结构及其用途,包括Documents、Library、Caches等关键目录的作用和存储规则,并提供了获取各目录路径的方法。

1.应用沙盒

出于安全考虑,iOS 系统的沙盒机制规定每个应用都只能访问当前沙盒目录下面的文件(也有例外,比如在用户授权情况下访问通讯录,相册等),这个规则展示了 iOS 系统的封闭性。在开发中常常需要数据存储的功能,比如存取文件,归档解档等。

1.1 沙盒目录结构

每个 APP 的沙盒下面都有相似目录结构,如图:

NSString *path = NSHomeDirectory();
复制代码

上面的代码得到的是应用程序目录的路径,在该目录下有三个文件夹:Documents、Library、temp 以及一个 .app 包。该目录下就是应用程序的沙盒,应用程序只能访问该目录下的文件夹。

  1. MyApp.app

    该目录包含了应用程序本身的数据,包括图片、plist文件、nib文件、国际化文件和可执行文件等。程序启动以后,会根据需要从该目录中动态加载代码或资源到内存,这里用到了懒加载的思想。为了防止被篡改,应用在安装的时候会将该目录签名。该路径下的文件不会被 iTunes 备份。

  2. Documents

    我们可以将应用程序的数据文件保存在该目录下。不过这些数据类型仅限于不可再生的数据,可再生的数据文件应该存放在 Library / Cache 目录下。该路径下的文件会被 iTunes 备份。

  3. Documents / Inbox

    该目录用来保存由外部应用请求当前应用程序打开的文件。比如我们的应用叫 A,向系统注册了几种可打开的文件格式,B 应用有一个 A 支持的格式的文件 F,并且申请调用 A 打开 F。由于 F 当前是在 B 应用的沙盒中,我们知道,沙盒机制是不允许 A 访问 B 沙盒中的文件,因此苹果的解决方案是讲 F 拷贝一份到 A 应用的 Documents / Inbox 目录下,再让 A 打开 F。该路径下的文件会被 iTunes 备份。

  4. Library

    苹果建议用来存放默认设置或其它状态信息,这个目录下有两个子目录:

    • Caches

      主要是缓存文件,用户使用过程中缓存都可以保存在这个目录中。前面说过,Documents 目录用于保存不可再生的文件,那么这个目录就用于保存那些可再生的文件,比如网络请求的数据。鉴于此,应用程序通常还需要负责删除这些文件。该路径下的文件不会被 iTunes 备份。

    • Preferences

      应用程序的偏好设置文件。我们使用 NSUserDefaults 写的设置数据都会保存到该目录下的一个 plist 文件中,这就是所谓的写道 plist 中。该路径下的文件会被 iTunes 备份。

  5. tmp

    各种临时文件,保存应用再次启动时不需要的文件。而且,当应用不再需要这些文件时应该主动将其删除,因为该目录下的东西随时有可能被系统清理掉,目前已知的一种可能清理的原因是系统磁盘存储空间不足的时候。该路径下的文件不会被 iTunes 备份。

1.2 获取各种文件目录的路径

获取目录路径的方法:

//获取沙盒主目录路径
NSString *homeDir = NSHomeDirectory();
//获取Documents目录路径
NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
//获取Library的目录路径
NSString *libDir = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject];
//获取Caches目录路径
NSString *cachesDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
//获取tmp目录路径
NSString *tmpDir =  NSTemporaryDirectory();
复制代码

NSSearchPathForDirectoriesInDomains方法中有三个参数:

  • directory

    NSSearchPathDirectory 类型的 enum 值,表明我们要搜索的目录名称,比如这里用 NSDocumentDirectory 表明我们要搜索的是 Documents 目录。如果我们将其换成 NSCachesDirectory 就表示我们搜索的是 Library / Caches 目录。

  • domainMask

    NSSearchPathDomainMask 类型的 enum 值,指定搜索范围,这里的 NSUserDomainMask 表示搜索的范围限制于当前应用的沙盒目录。还可以写成 NSLocalDomainMask(表示 /Library)、NSNetworkDomainMask(表示 /Network)等。

  • expandTilde

    BOOL 值,表示是否展开波浪线 ~。我们知道在iOS中 ~ 的全写形式是 /User/userName,该值为 YES 即表示写成全写形式,为 NO 就表示直接写成“~”。

获取应用程序程序包 (Myapp.app) 中资源文件路径的方法:

NSLog(@"%@",[[NSBundle mainBundle] bundlePath]);
NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"apple" ofType:@"png"];
UIImage *appleImage = [[UIImage alloc] initWithContentsOfFile:imagePath];
复制代码

2.plist 归档

“归档”意思是持久化存储数据。plist 文件是一种 XML 格式的文件,拓展名为 plist。如果对象是 NSString、NSDictionary、NSArray、NSData、NSNumber 等类型,就可以使用 writeToFile:atomically: 方法直接将对象写到属性列表文件(plist文件)中。特别注意的是 plist 文件不能存储对象。

//读取plist文件
NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"contact" ofType:@"plist"];
NSArray *allContacts = [NSArray arrayWithContentsOfFile: plistPath];
for (NSDictionary *dict in allContacts) {
	NSString *name = dict[@"name"];
 	NSString *phoneNumber= dict[@"phoneNumber"];
	NSString *address = dict[@"address"];
	NSLog(@"%@,%@,%@",name, phoneNumber, address);
}

//写入plist文件
NSMutableArray *myArray = [NSMutableArray array];
NSDictionary *dict1 = @{
                        @"name":@"赵六",
                        @"address":@"北京"                         };
NSDictionary *dict2 = @{
                        @"name":@"钱七",
                        @"address":@"上海"
                        };
[myArray addObject: dict1];
[myArray addObject: dict2];
[myArray writeToFile:@"/users/tarena/desktop/aaa.plist" atomically:YES];
复制代码

3.参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值