数据存储的核心都是写文件,主要有四种持久化方式:属性列表(Plist),对象序列化,SQLite数据库,CoreData。
存储Plist:
键值进行存储,不能存储对象。对象需要序列化编码才能写入文件。NSAarry,NSDictionary,NSData,NSString等类型可以直接调用writeToFile方法把数据存储到plist文件中,但是数组中的元素或者字典中的元素必须是下面的七种类型:NSData,NSArray,NSDictionary,NSDate,NSString,NSNumber,Boolean。
NSUserDefault本质上也是存储到plist文件中,所以存入NSUserDefault当中的对象也应该满足以上七种类型。
应用与少量数据存储,比如登陆的用户信息,应用程序配置信息等。
对象序列化:
最终也是存为属性列表文件,如果程序中,需要存储对象属性的时候,直接存储对象比较方便,例如有一个设置类,我们可以把设置类的对象直接存储,就没必要再把里面的每一个属性单独存到文件中,对象序列化是将一个实现了NSCoding协议的对象,通过序列化(NSKeyedArchiver)的形式,将对象中的属性抽取出来,转换成二进制流,也就是NSData,NSData可以选择writeToFile或者存储到NSUserdefault中,必须实现两个方法encodeWithCoder,initWithCoder。对象NSData。
NSObject<NSCoding>=====(NSKeyedArchiver)=====>>NSData=====(writeToFile)=====>>File
||
||
||
||
NSUserDefault
数据库SQLite:
NSOutputStream,NSInputStream
适合大量,重复,有规律的数据存储,而且频繁的读取,删除,过滤数据,这种适合使用数据库。重用的增删改查语句,使用第三方库FMDB更好的处理数据。
CoreData:(以对象方式操作数据库)
SQLite叫做关系型数据库,CoreData是一种OR-Mapping的思想,O代表对象Object,R代表relationship,Mapping代表映射,直译过来就是对象关系映射,其实就是把对象的属性和表中的字段自动映射,简化程序员的负担,以面向对象的方式操作数据库。ORMapping是一种思想,CoreData实现了这种思想,在Java中,hibernate也是ORMapping的一种实现。
CoreData本质还是数据库,只不过使用起来更加面向对象,不关注二维的表结构,而是只需要关注对象,纯面向对象的数据操作方式。我们直接使用数据库的时候,如果向数据库中插入数据,一般是把一个对象的属性和数据库中某个表的字段一一对应,然后把对象的属性存储到具体的表字段中,取一条数据的时候,把表中的一行数据取出,同样需要再封装到对象的属性中,这样的方式有点繁琐,不面向对象。CoreData解决的问题就是不需要这个中间的转换过程,看起来是直接把对象存储进去,并且取出,不关心表的存在,实际内部已经帮你做好了映射关系。
CoreData中经常使用的类:
NSManagedObjectContext管理对象上下文:相当于FMDB中的FMDatabase对象,我们对数据中的操作先存储到这个上下文中,然后把操作同步到数据库中。
NSManagedObject托管对象:相当于是对表中一行数据的封装。
NSEntityDescription实体描述:相当于在这个对象中定义了数据库中表的结构,比如包含哪些字段等。
NSPersistentStoreCoordinator持久化存储协调器:链接数据库的类,里面包含了数据库的位置,名称等,相当于文件管理器,帮我们创建数据库文件等。
NSMangedObjectModel托管对象模型:里面包含了数据库表,表之间关系的设计模型。其实这个对象里面包含的就是我们使用CoreData时,设计数据库模型Xcdatamodel文件中的信息。
最后说一下所有的本地持久化数据存储的本质都是写文件,而且只能存到沙盒文件中。沙盒机制是苹果的一项安全机制,本质就是系统给每个应用分配了一个文件夹来存储数据,而且每个应用只能访问分配给自己的那个文件夹,其他应用的文件夹是不能访问的。
沙盒中默认的三个文件夹(支持自己创建新的文件夹):
1、Documents:存储用户相关的数据(用户拍的视频,用户创作的图片,用户唱的歌曲,用户收藏的商品等等)。
2、Library:跟程序相关的数据(程序缓存,程序的配置文件等等)。
3、Temp:放临时文件,不需要永久存储的,比如下载的时候,需要存储到临时文件中,最终copy到Documents或Library中。