概论
所谓的持久化,就是将数据保存到硬盘中,使得在应用程序或机器重启后可以继续访问之前保存的数据。在iOS开发中,有很多数据持久化的方案,接下来我将尝试着介绍一下5种方案:
plist文件(属性列表)
preference(偏好设置)
NSKeyedArchiver(归档)
SQLite 3
CoreData
沙盒:
iOS程序默认情况下只能访问程序自己的目录,这个目录被称为“沙盒”。
沙盒的本质是一个文件夹,名字是随机分配的。
沙盒的目录结构如下
获取沙盒主路径
// 获取沙河主路径
NSString * homePath = NSHomeDirectory();
Document :最常用的目录,iTunes同步该应用时会同步此文件夹中的内容,适合存储重要数据。(例如数据库等)
// iTunes 在备份的时候会自动备份此文件
NSString * documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory, NSUserDomainMask, NO) objectAtIndex:0];
Library
// library:通常用来存储应用程序运行期间生成的持久化数据, 比如用户账号等。应用程序退出后不会被删除文件夹内数据,但是iTunes 备份不会备份此文件。
NSString * libraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0];
Library/Caches: iTunes不会同步此文件夹,适合存储体积大,不需要备份的非重要数据。
// library下的cache :运行期间的缓存文件 历史记录等。
NSString * cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)objectAtIndex:0];
Library/Preferences: iTunes同步该应用时会同步此文件夹中的内容,通常保存应用的设置信息。例如:应用程序的设置,夜间模式等
// 正常方法错误 NSString * preferencePath = [NSSearchPathForDirectoriesInDomains(NSPreferencePanesDirectory, NSUserDomainMask, YES)objectAtIndex:0]; 错误
// 需要使用特殊方法 (拼接路径)library路径拼接preferences获取 此路径。
NSString * preferencePath = [libraryPath stringByAppendingString:@"/Preferences"];
Temp:iTunes不会同步此文件夹,系统可能在应用没运行时就删除该目录下的文件,所以此目录适合保存应用中的一些临时文件,用完就删除。
NSString * tempPath = NSTemporaryDirectory();
NSBundle
“应用程序包”: 这里面存放的是应用程序的源文件,包括资源文件和可执行文件。
// 获取当前应用程序包
NSBundle * bundle = [NSBundle mainBundle];
// 获取当前包的路径
NSString * bundlePath = [bundle resourcePath];
// 或者
// NSString * bundlePath = [bundle bundlePath];
NSLog(@"bundlePath = %@",bundlePath);
//获取包内文件内容
NSString * imagePath = [bundle pathForResource:@"2" ofType:@"jpg"];
NSString * indexFacepath = [bundle pathForResource:@"蓝欧接口文档" ofType:@"txt"];
plist 文件
plist文件是将某些特定的类,通过XML文件的方式保存在目录中。
可以被序列化的类型只有如下几种:
NSArray;
NSMutableArray;
NSDictionary;
NSMutableDictionary;
NSData;
NSMutableData;
NSString;
NSMutableString;
NSNumbe
1、 获取文件路径
//(参数1:路径NSDocumentDirectory 参数2:在本地上的NSUserDomainMask 参数3:YES返回一个完整的路径,NO 返回相对路径)
NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
NSString *fileName = [path stringByAppendingPathComponent:@"123.plist"];
NSArray *array = @[@"123", @"456", @"789"];
[array writeToFile:fileName atomically:YES];
3.读取
NSArray *result = [NSArray arrayWithContentsOfFile:fileName];
NSLog(@"%@", result);
4.注意:
1) 只有以上列出的类型才能使用plist文件存储。
2)存储时使用writeToFile: atomically:方法。 其中atomically表示是否需 要先写入一个辅助文件,再把辅助文件拷贝到目标文件地址。这是更安全的写入文件方法,一般都写YES。
3)读取时使用arrayWithContentsOfFile:方法。
NSString * incantation = @"何如薄幸锦衣郎,比翼连枝当日愿";
//获取主路径
NSString * path = NSHomeDirectory();
// 添加路径名称,格式可以是任何类型。
path = [path stringByAppendingString:@"/Nalanrongruo.mp3"];
// 如果是YES,传输失败文件终端会保存,一般YES 写入的时候使用NSUTF8StringEncoding,读出时仍然要使用 NSUTF8StringEncoding。要一致
[incantation writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:nil];
NSLog(@"%@",path);
// 从文件中取出内容
NSString * resultString = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
NSLog(@"%@",resultString);
数组写入文件 :NSArray
NSArray * array = @[@"相怜相念倍相亲",@"一生一世一代人"];
NSString * path = NSHomeDirectory();
path = [path stringByAppendingPathComponent:@"王安石.txt"];
// 写入
[array writeToFile:path atomically:YES];
NSLog(@"%@",path);
// 读取
NSArray * resultArray = [NSArray arrayWithContentsOfFile:path];
NSLog(@"%@",resultArray[0]);
字典写入: NSDictionary
NSDictionary * dict = @{@"李清照":@"泪泠泠"};
NSString * path = NSHomeDirectory();
path = [path stringByAppendingPathComponent:@"李清照.txt"];
// 写入
[dict writeToFile:path atomically:YES];
NSLog(@"%@",path);
// 读出
NSDictionary * resultDict = [NSDictionary dictionaryWithContentsOfFile:path];
NSLog(@"%@",resultDict);
图片写入:NSData
照片类型的比较特殊,需要先将照片转化存入到NSData 类型中,然后把NSData 类型存入到文件中,读取的时候也是首先读取NSData 类型,再转换成UIImage 类型。
// 图片写入
UIImage * iamge = [UIImage imageNamed:@"LZ.jpg"];
// 参数 0~1 之间,放大缩小的比例
NSData * data = UIImageJPEGRepresentation(iamge, 1);
NSString * path = NSHomeDirectory();
path = [path stringByAppendingString:@"LZ.aaa"];
//写入
[data writeToFile:path atomically:YES];
//读取
NSData * resultData = [NSData dataWithContentsOfFile:path];
UIImage * resultImage = [UIImage imageWithData:resultData];