程序员人生 网站导航

iOS 优化内存(八)持久化

栏目:综合技术时间:2015-03-30 08:08:53

iOS持久化


1.文件系统

不论是Mac OS X 还是iOS的文件系统都是建立在UNIX文件系统基础之上的。

1.1 沙盒模型

在iOS中,1个App的读写权限只局限于自己的沙盒目录中。

沙盒模型到底有哪些好处呢?
安全:别的App没法修改你的程序或数据
保护隐私:别的App没法读取你的程序和数据
方便删除:由于1个App所有产生的内容都在自己的沙盒中,所以删除App只需要将沙盒删除就能够完全删除程序了

iOS App沙盒中的目录

  • App Bundle ,如xxx.app 实际上是1个目录,里面有app本身的2进制数据和资源文件
  • Documents, 寄存程序产生的文档数据
  • Library , 下面默许包括下面两个目录 Caches Preferences
  • tmp, 临时文件目录

如果我们想在程序中获得上面某个目录的路径,应当如何实现呢? 下面就讲讲路径的获得, 通过NSPathUtilities.h中的NSSearchPathForDirectoriesInDomains函数,我们即可以获得我们想要的路 径。 此函数具体声明以下:

NSArray *NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory directory, NSSearchPathDomainMask domainMask, BOOL expandTilde); 
directory 目录类型 比如Documents目录 就是NSDocumentDirectory 
domainMask 在iOS的程序中这个取NSUserDomainMask 
expandTilde YES,表示将~展开成完全路径

注意函数返回的类型为数组,在iOS中1般这个数组中只包括1个元素,所以直接取lastObject便可。

1.2 NSFileManager

NSFileManager提供1个类方法取得1个单例。

  1. /* Returns the default singleton instance.*/ + (NSFileManager *)defaultManager; 

下面罗列了NSFileManager的经常使用方法

  • 新建目录

  1. - (BOOL)createDirectoryAtPath:(NSString *)path withIntermediateDirectories:(BOOL)createIntermediates attributes:(NSDictionary *)attributes error:(NSError **)error; 

createIntermediates这个参数1般为YES,表示如果目录路径中间的某个目录不存在则创建之,如果是NO的话,则要保证所创建目录的父目录都必须已存在

  • 获得目录下的所有文件
  1. - (NSArray *)contentsOfDirectoryAtPath:(NSString *)path error:(NSError **)error; 

如果目录为空,则返回空数组

  • 其他的1些方法

  1. - (BOOL)copyItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath error:(NSError **)error; - (BOOL)moveItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath error:(NSError **)error; - (BOOL)linkItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath error:(NSError **)error; - (BOOL)removeItemAtPath:(NSString *)path error:(NSError **)error; 

更多的可以查看文档 NSFileManager Class Reference。

在实际项目中,我们1般会写1个工具类来负责项目中所有的路径操作。

2. 归档(Archives) 和 序列化(Serializations)

我们常常听到“序列化”,“反序列化”这样的字眼,其实“序列化”的意思就是将对象转换成字节流以便保存或传输,“反序列化”便是1个相反的进程,从字节流转到对象。

在这节中触及到1种文件类型plist,plist就是Property List 的缩写,即所谓的属性列表,属性列表有两种数据格式,1种是XML的,方便浏览和编辑;另外一种是2进制的,节省存储空间,和提高效力。

在Objective-C中这个对象和字节流的互转分成两类:

  • 归档 普通自定义对象和字节流之间的转换
  • 序列化 某些特定类型(NSDictionary, NSArray, NSString, NSDate, NSNumber,NSData)的数据和字节流之间(通常将其保存为plist文件)的转换

不过本质上讲上述两种都是对象图(Object Graph)和字节流之间的转换. Apple关于序列化和归档的编程指南: Archives and Serializations Programming Guide 。

2.1 归档

如果我们需要将自定义的1个对象保存到文件,应当如何做呢? 
这里引入两个东西:1个是NSCoding协议 ;另外一个是NSKeyedArchiver,NSKeyedArchiver其实继承于NSCoder,可以以键值对的方式将对象的属性进行序列化和反序列化。 
具体的进程可以这样描写 通过NSKeyedArchiver 可以将实现了NSCoding协议的对象 和 字节流 相互转换 。

像1些框架中的数据类型如NSDictionary,NSArray,NSString... 都已实现了NSCoding协议,所以可以直接对他们进行归档操作。

这里来1个比较完全的例子,1个Address类,1个User类,User类下有个Address类型的属性。

Address类

User类

使用示例

通过查看文件内容可以发现,保存的是plist的2进制数据格式。 转成XML可以看到以下内容:

2.2 序列化

在实际的项目中,我们1般是将NSDictionary或NSArray的对象保存到文件或从文件读取成对象。 固然这类只是适用于数据量不是很大的利用场景。 NSDictionary和NSArray 都有1个写入文件的方法

NSDictionary和NSArray会直接写成plist文件。

2.2.1 序列化的方式

序列化可以通过两种途径来进行

使用数据对象自带的方法

写文件

写完的文件内容以下:


现在 持久化数据用第3方的比较多!

------分隔线----------------------------
------分隔线----------------------------

最新技术推荐