- iOS 中的永久存储,也就是在关机重新启动设备,或者关闭应用时,不会丢失数据.在 iOS 开发过程中,总会遇到需要持久存储数据的这样用户才能对应用进行操作胡,再次启动能看到自己更改过的结果与痕迹.
- 所以在 iOS 开发中,我们需要数据持久化这一种技术,也需要不断在实际开发的工作与学习中完善数据持久化这已开发技术.
- 有四种数据持久化的方法:分别是,属性列表.对象的归档与解档.数据库 sqlite3的运用以及 coreData 的运用.
在介绍4中持久化存储方式前,我们先需要了解3个有关的文件夹.以及什么是沙盒机制.
- -Documents; 应用会将数据存储在这个文件夹里,但是基于 NSUserDefauls 的首选项设置除外;
-
- Library; 基于NSUserDefauls的首选项设置存储在 library\Preferences 文件夹中.且 Library 下面有 Preferences 和 Caches 目录.
-
- tmp; 供应用存储临时文件,当 iOS 设备进行同步操作时, iTunes 并不会备份这个文件夹的文件,但是在不需要这些文件的时候.应用需要删除 tm 中的这些文件.以免占用文件系统空间.
什么是沙盒机制
我们手中 iPhone/iPad 设备上包含着闪存,它的功能和一个硬盘功能等价.当设备断电后数据依然能够保存下来,应用程序可以把数据文件保存到闪存上.并且读取它们,但是,需要注意的是.我们所开发的应用程序是无法访问整个闪存的,因为闪存上面会专门有一部分给我们,这一部分就是属于我们开发的这个应用程序的沙盒(sandBox)了.iOS 系统中,每个应用都只能看到自己的沙盒.这就是防止对其它应用程序的数据文件进行读写活动.就像我们的应用程序也能够看到一些系统拥有的高级别目录,但是却无法尽心任何的写入操作.
那么,如何获取自己的目录?
1.获取Documents目录
由于 iOS 中应用的数据存储是沙盒机制,因此读取和写入文件.我们需要调用 C 函数NSSearchPathForDirectoriesInDomains()
来查找各种目录,(这个 C 函数可以基于 Mac OSX 平台的 cocoa 共享)
如检索Documents目录路径的代码:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
NSString*pathDirectory= [paths objectAtIndex:0];
//第一个常量NSDocumentDirectory表示我们正在查找目录的路径,第二个常量
NSUserDomainMask表明我们希望将搜索限制在应用的沙盒内;(在 Mac OSX 中,此常量表示我们希望该函数查看用户的主目录,因此才会有这个命名);
//返回的一个数据 paths, 为什么位于索引0就是我们需要的 Document 目录?因为每一个应用只有一个 Document 目录,一次只有一个目录符合这个条件;接下来,我们可以为刚才检索到的目录 pathDirectory 的结尾加上一个字符串来创建一个文件名.如下;
NSString *filename = [pathDirectory stringByAppendingPathComponent:@"data.txt"];
这个时候我呢得到的 filename 字符串就可进行创建\读取\写入文件了
2.获取 tmp 目录;
可以用NSTemporaryDirectory()
的 Foundation
函数返回一个字符串,该字符串包含到应用临时目录的完整路径.同上.在结尾附上文件名就可以创建指向该目录下的文件路径了.
NSString *tmpPath = NSTemporaryDirectory();
NSString *temFile = [tmpPath stringByAppendingPathComponent:@"tempFile.txt"];
- 一.属性列表
什么是序列化对象:
序列化对象,是指可以被转换为字节流以便于存储到文件中或者通过网络进行传输的对象;
虽然说任何对象都可以被序列化,但是只有某些特定的对象才能防止到某个集合类(例如; NSArray\NSMutalbleArray\NSDictionary\NSData 等)中,并使用该集合类的方法在属性列表存储中使用,其他的对象也可以使用归档的方法进行存储.
简单的使用一下.具体的功能效果如图1,可以让用在4个文本框中输入数据,应用退出时会把这些字段保存到属性列表中,便在下次启动时重现加载恢复上次的数据;
在 Xcode 中,使用 Single View Application 模板创建一个新的项目,命名规则随意. 在main.storyboard
中拖入4个标签,4个文本框架,拖动并对齐标签与文本框,并依次修改标签文本如图1,ViewController. h
中添加一个装载4个文本框的数组.lineFields
;
#import
@interface ViewController : UIViewController
@property (strong,nonatomic)
IBOutletCollection(UITextField) NSArray *lineFields;@end
打开辅助编辑器,通过control键将4个文本框连接到 lineFields 这个数组,确保连接顺序为从顶部到底部!
在项目导航面板中,点击”ViewController.m” ,将以下代码添加到@implementation与 @end 的中间,这个方法在后面会一直调用:
/获取属性列表路径中数据文件的完整路径 dataFilepath
//需要加载和保存数据的代码都可以调用该方法.
-(NSString *)dataFilepath{
NSArray *paths =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *pathDirectory = [paths objectAtIndex:0];
return [pathDirectory stringByAppendingPathComponent:@"data.txt"];
}
接下来,在viewDidload中添加代码,并添加相应的响应器方法:
- (void)viewDidLoad {
[super viewDidLoad];
NSString *filePath = [self dataFilepath];
//判断是否存在属性列表文件
if([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
//存在,则把数据赋值给文本框
NSArray *ar= [[NSArray alloc]initWithContentsOfFile:filePath];
这段代码的意思是,首先检查完整路径下的数据文件是否存在,不存在的话就不加载了.
若存在,则把数组中的对象赋值到4个文本框中,根据刚才我们创建数组lineFields
的时候,与文本框的连接顺序,就可以把数据赋值给文本框了.
人后在应用终止或者进入后台之前记性数据的保存处理,所以我们使用通知中心,订阅了名为"UIApplicationWillResignActiveNotification"的通知,并在后面事项了applicationWillResignActiveNotification
这个方法.
当用户按下 home键时,或者其他事件发生(比如来电)导致应用进入后台的情况下,变调此方法,把字符串数组写入我们创建的属性列表文件里面.
如果没有其他问题的话,我们可以分别键入4个文本框,然后点击Home键(也就是command+shift+H)、双击Home键(按住command+shift,双击H),或者在Xcode中终止应用退出模拟器(相当于手机重启),以验证数据在应用得到永久保存了。
总结:属性列表的序列化很实用,也相对比较简单,但是也会有点限制,就是只能讲一小部分对象保存在属性列表中.