本地数据持久化方法
http://www.jianshu.com/p/86ea6da905cf
http://www.cocoachina.com/industry/20130328/5908.html
1. 属性列表(plist)NSUserDefaults
属性列表是一种明文的轻量级存储方式,其存储格式有多种,最常规格式为XML格式。在我们创建一个新的项目的时候,Xcode会自动生成一个info.plist文件用来存储项目的部分系统设置。plist只能用数组(NSArray)或者字典(NSDictionary)进行读取,由于属性列表本身不加密,所以安全性几乎可以说为零。因为,属性列表正常用于存储少量的并且不重要的数据。
在程序启动后,系统会自动创建一个NSUserDefaults的单例对象,我们可以获取这个单例来存储少量的数据,它会将输出存储在.plist格式的文件中。其优点是像字典一样的赋值方式方便简单,但缺点是无法存储自定义的数据。
2. 数据归档(NSKeyedValueArchiver)
与属性列表相反,同样作为轻量级存储的持久化方案,数据归档是进行加密处理的,数据在经过归档处理会转换成二进制数据,所以安全性要远远高于属性列表。另外使用归档方式,我们可以将复杂的对象写入文件中,并且不管添加多少对象,将对象写入磁盘的方式都是一样的。
要使用对象归档,对象必须实现NSCoding协议。大部分Objective-C对象都符合NSCoding协议,也可以在自定义对象中实现NSCoding协议。要实现NSCoding协议,要实现两个方法:encodeWithCoder和initWithCoder。
使用NSKeyedArchiver对自定义的数据进行序列化,并且保存在沙盒目录下。使用这种归档的前提是让存储的数据模型遵守NSCoding协议并且实现其两个协议方法。(当然,如果为了更加安全的存储,也可以遵守NSSecureCoding协议,这是iOS6之后新增的特性)
3. 数据库(sqlite)
sqlite是一个轻量级、跨平台的小型数据库,其拥有可移植性高、有着和MySql几乎相同的数据库语句以及无需服务器即可使用的优点:
一、可以存储大量的数据,存储和检索的速度非常快;
二、能对数据进行大量的聚合,这样比起使用对象来进行这些操作要快。
当然,它也具有明显的缺点:
一、它没有提供数据库的创建方式;
二、它基于C语言框架设计,没有面向对象的API,所以使用起来比较麻烦;
三、复杂的数据模型的数据建表相对而言比较麻烦。
当然,我们也可以使用基于sqlite封装的开源数据库FMDB来减少使用sqlite的工作量。
SQLite嵌入到使用它的应用程序中,它们共用相同的进程空间,而不是单独的一个进程。从外部看,它并不像一个RDBMS,但在进程内部,它却是完整的,自包含的数据库引擎。
4. coreData
Core Data本质上是使用SQLite保存数据,但是它不需要编写任何SQL语句。
要使用Core Data,需要在Xcode中的数据模型编辑器中设计好各个实体以及定义好他们的属性和关系。之后,通过操作这些对象,结合Core Data完成数据的持久化。
coreData是苹果官方iOS5之后推出的综合型数据库,其使用了ORM(Object Relational Mapping)对象关系映射技术,将对象转换成数据,存储在本地数据库中。coreData为了提高效率,甚至将数据存储在不同的数据库中,且在使用的时候将本地数据放到内存中使得访问速度更快。我们可以选择coreData的数据存储方式,包括sqlite、xml等格式。但也正是coreData 是完全面向对象的,其在执行效率上比不上原生的数据库。除此之外,coreData拥有数据验证、undo等其他功能,在功能上是四种持久化方案最多的。
近用了一下归档保存,很简单的应用,就是把一个数组归档保存到沙盒,在模拟器上跑起来是没问题的,可是运行到真机上连接xcode测试就是归档失败,废话少说,直接说解决办法,Google了一下,直接导向了stackoverflow了:
本人源代码如下:
//归档保存搜索历史记录muArrayFindHistory,一旦离开这个页面,立即归档保存记录
NSString *localPath = @"muArrayFindHistory.src";
NSString * pathMuArrayFindHistory = [NSHomeDirectory() stringByAppendingPathComponent:localPath];
BOOL success = [NSKeyedArchiver archiveRootObject:self.muArrayFindHistory toFile:pathMuArrayFindHistory];
此处success在模拟器上返回是YES,在真机上返回时NO,
解决办法:
//归档保存搜索历史记录muArrayFindHistory,一旦离开这个页面,立即归档保存记录
NSString *localPath = @"Documents/muArrayFindHistory.src";
NSString * pathMuArrayFindHistory = [NSHomeDirectory() stringByAppendingPathComponent:localPath];
BOOL success = [NSKeyedArchiver archiveRootObject:self.muArrayFindHistory toFile:pathMuArrayFindHistory];
这样制定一下路径成功了.
stackoverflow上的疑问与解答:
原文网址:http://stackoverflow.com/questions/963175/nskeyedarchiver-works-in-iphone-simulator-fails-on-device
大概意思是说在模拟器上只要在沙盒中给定了路径就可以,可是在真机上需要更明确一下.
在我做一款app的时候,需要运用到归档保存数据,模拟可以,可是真机不行,就像上面说的需要一个明确的路径 Documents/ 。基本需要有路径这种保存数据的,都需要这个Documents/ 。