IOS应用中的数据存储
来源:互联网 发布:联想笔记本网络驱动 编辑:程序博客网 时间:2024/05/01 02:44
介绍
概述
无论是IOS应用或者是其它的网页应用,都有数据存储。在IOS中,数据存储的方式主要有五种。这五种方式各自有着各自的特点,使用的时候我们需要分清具体情况然后选择最合适的存储方式。这五种方式分别是:
- XML属性列表(plist)
- Preference(偏好设置)
- NSKeyedArchiver归档(NSCoding)
- SQLite3
- Core Data
对于沙盒的介绍Scandbox
每个ios应用都有自己的沙盒(所谓的沙盒就是应用的文件系统),与其他文件系统隔离。应用必须待在自己的沙盒里,其他应用不能访问本应用的沙盒。
应用沙盒的文件系统目录,如下图所示:
它里面的内容具体包括:
- 应用程序包
- Documents:保存应用运行时生成的需要持久化的数据,iTunes同步设备时会备份该目录。
- temp:保存应用运行时所需的临时数据,使用完毕后再将相应的文件从该目录删除。应用没有运行时,系统也可能会清除该目录下的文件。iTunes同步设备时不会备份该目录
- Library/Caches:保存应用运行时生成的需要持久化的数据,iTUnes同步设备时不会备份该目录。一般存储体积大,不需要备份的非重要数据
- Library/Preference:保存应用的所有偏好设置,ios的Settings(设置)应用汇在该目录中查找应用的设置消息。iTunes同步设备时会备份该目录。
应用沙盒目录的常见获取方式:
- 沙盒根目录:NSString *home = NSHomeDirectory();
- Documents:(2种方式):
1.利用沙盒根目录直接拼接“Documents”字符串
NSString *home = NSHomeDirectory(); NSString *documents = [home stringByAppendingPathComponent:@"Documents"];
不建议采用上面的方法,因为新版本的操作系统可能会修改目录名。
2.利用NSSearchPathForDirectoriesInDomans函数
NSString *documentsDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSUserDomanMask:代表从用户文件夹下找
YES:代表展开路径中的波浪字符‘~’
在ios中,只有一个目录跟传入的参数匹配,所以这个集合里面只有一个元素。
- temp目录:NSString *temp = NSTemporaryDirectory();
- Library/Caches:跟Documents类似的两种方法
1.利用沙盒根目录拼接“Caches”字符串
2.利用NSSearchPathForDirectoriesInDomains函数(将函数的第2个参数改为:NSCachesDirectory即可)
- Library/Preference:通过NSUserDefaults类存取该目录下的设置信息。
一、属性列表存储
属性列表是一种XML格式的文件,其扩展名为plist;如果对象是NSString、NSDictionary、NSArray、NSData、NSNumber等烈性,就可以使用writeToFile:automically:方法直接将对象写到属性列表文件中。
eg:把一个NSDictionary写入plist文件并读取:
- (void)saveDictToDocuments{ NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; NSString *path = [NSString stringWithFormat:@"%@/animal.plist",documentPath]; NSMutableDictionary *dict = [NSMutableDictionary dictionary]; [dict setObject:@"ZhuBaJie" forKey:@"name"]; [dict setObject:@"27" forKey:@"age"]; [dict setObject:@"gao lao zhuang" forKey:@"address"]; if([dict writeToFile:path atomically:YES]) { NSLog(@"写入数据成功"); }}- (void)readDictFormDocuments{ NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; NSString *path = [NSString stringWithFormat:@"%@/animal.plist",documentPath]; NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path]; NSLog(@"%@",dict);}
运行结果:
2016-03-10 18:14:15.557 SandboxTest[7069:2123397] { address = "gao lao zhuang"; age = 27; name = ZhuBaJie;}
二、偏好设置
很多iOS应用都支持偏好设置,比如保存用户名、密码、字体大小等设置,iOS提供了一套标准的解决方案来为应用加入偏好设置功能。每个应用都有个NSUserDefaults实例,通过它来存取偏好设置。比如,保存用户名、字体大小、是否自动登录
注意事项:使用NSUserDefaults设置数据时,不是立即写入,而是根据时间戳定时地把缓冲中的数据写入本地磁盘。所以调用了set方法之后数据有可能还没有写入磁盘应用程序就终止了。出现以上问题可以通过调用syncharonize方法强制写入。[[NSUserDefaults standardUserDefaults] synchronize];
三、NSKeyedArchiver
如果对象是NSString、NSDictionary、NSArray、NSData、NSNumber等类型,就可以直接使用NSKeyedArchiver进行归档和恢复。
不是所有的对象都可以直接用这种方法机型归档,只有遵循了NSCoding协议的对象才可以。
NSCoding协议有两个方法:
- encodeWithCoder:
每次归档对象时,都会调用这个方法。一般在这个方法里面指定如何归档对象中的每个实例变量,可以使用encodeObject:forKey:方法归档实例变量。 - initWithCoder:
每次从文件中恢复(解码)对象时,都会调用这个方法。一般在这个方法里面指定如何解码文件中的数据为对象的实例变量,可以使用decodeObject:forKey方法解码实例变量。
eg:把array归档存储和读取
- (void)saveArrayToDocuments{ NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; NSString *path = [NSString stringWithFormat:@"%@/array.archive",documentPath]; NSArray *array = [NSArray arrayWithObjects:@"a",@"b",@"c", nil]; if ([NSKeyedArchiver archiveRootObject:array toFile:path]) { NSLog(@"数据写入成功"); }}- (void)readArrayFromDocuments{ NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; NSString *path = [NSString stringWithFormat:@"%@/array.archive",documentPath]; NSArray *array = [NSKeyedUnarchiver unarchiveObjectWithFile:path]; NSLog(@"%@",array);}
运行结果:
2016-03-10 18:39:03.780 SandboxTest[7093:2128040] ( a, b, c)
eg:把Person对象归档存储和读取
- (void)savePersonObjToArchive{ NSString *document = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; NSString *path = [NSString stringWithFormat:@"%@/person.archive",document]; Person *person = [[Person alloc] init]; person.name = @"JonQi"; person.age = 20; person.height = 1.80f; if ([NSKeyedArchiver archiveRootObject:person toFile:path]) { NSLog(@"对象保存成功"); }}- (void)readPersonObjFromArchive{ NSString *document = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; NSString *path = [NSString stringWithFormat:@"%@/person.archive",document]; Person *person = [NSKeyedUnarchiver unarchiveObjectWithFile:path]; NSLog(@"Person object:name=%@,age=%d,height=%f",person.name,person.age,person.height);}
运行结果:
2016-03-10 21:23:51.968 ScandboxTest[3424:39823] Person object:name=JonQi,age=20,height=1.800000
使用NSKeyedArchiver进行归档对象时请注意:
- 如果父类也遵守了NSCoding协议,应该在encodeWithCoder:方法中加上一句[super encodeWithCode:encode];确保继承的实例变量也能被编码,即也能被归档;应该在initWithCoder:方法中加上一句self = [super initWithCoder:decoder];确保继承的实例变量也能被解码,即也能被恢复。
- 使用archiveRootObject:toFile:方法可以将一个对象直接写入到一个文件中,但有时候可能将多个对象写入到同一个文件中,那么就要使用NSData来进行归档对象。
NSData可以为一些数据提供临时存储空间,以便随后写入文件,或者存放从磁盘读取文件内容。可以使用[NSMutableData data]创建可变数据空间。如图
eg:利用NSData存储多个对象到同一个文件中以及读取多个对象:
- (void)savePersonObjToArchive{ NSString *document = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; NSString *path = [NSString stringWithFormat:@"%@/person.archive",document]; Person *person1 = [[Person alloc] init]; person1.name = @"JonQi"; person1.age = 20; person1.height = 1.80f; Person *person2 = [[Person alloc] init]; person2.name = @"XiaoM"; person2.age = 10; person2.height = 1.60f; // 创建一块可变数据区 NSMutableData *mutableData = [NSMutableData data]; // 将数据区连接到一个NSKeyedARchiver对象 NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:mutableData]; // 开始存档对象,存档的数据都会存储到NSMutableData中 [archiver encodeObject:person1 forKey:@"person1"]; [archiver encodeObject:person2 forKey:@"person2"]; // 存档完毕,一定要调用的方法 [archiver finishEncoding]; [mutableData writeToFile:path atomically:YES];}- (void)readPersonObjFromArchive{ NSString *document = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; NSString *path = [NSString stringWithFormat:@"%@/person.archive",document]; NSData *data = [NSData dataWithContentsOfFile:path]; NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; Person *person1 = [unarchiver decodeObjectForKey:@"person1"]; Person *person2 = [unarchiver decodeObjectForKey:@"person2"]; [unarchiver finishDecoding]; NSLog(@"person1 object:name=%@,age=%d,height=%f",person1.name,person1.age,person1.height); NSLog(@"person2 object:name=%@,age=%d,height=%f",person2.name,person2.age,person2.height);}
运行结果:
2016-03-10 21:46:57.285 ScandboxTest[4907:60533] person1 object:name=JonQi,age=20,height=1.8000002016-03-10 21:46:57.285 ScandboxTest[4907:60533] person2 object:name=XiaoM,age=10,height=1.600000
利用归档实现深复制:
- IOS应用中的数据存储
- iOS 应用数据存储
- ios中的数据存储
- ios应用数据存储方式(plist存储)
- ios中的数据存储方式
- 详解iOS中的数据存储
- ios之应用数据存储三:SQLite
- ios之应用数据存储四:CoreData
- ios之应用数据存储五:writeToFile
- iOS应用数据存储的常用方式
- iOS应用数据存储的常用方式
- ios应用数据存储方式(偏好设置)
- ios应用数据存储方式(归档)
- iOS应用数据存储的常用方式
- Plist—ios应用数据存储方式
- 归档—ios应用数据存储方式
- iOS应用数据存储的常用方式
- ios应用数据存储方式(偏好设置)
- HDU 2.1.3 Cake
- 使用RSS管理信息获取源
- 数据库表查询的一些知识点
- iOS登录界面和注册界面
- HDU 2.1.4 又见GCD
- IOS应用中的数据存储
- 线程(三)--线程控制-线程的优先级
- Nginx:Purge,ngx_cache_purge模块
- LeetCode - 1. Two Sum
- HDU 2.1.5 七夕节
- 微信企业号开发可能遇到的问题
- ContentResolver
- 线程(四)--线程控制-沉睡
- Hust oj 2234 土豪银行(贪心)