存储形式介绍
- NSKeyedArchiver: 采纳归档的模式来保留数据沙盒中;
- NSUserDefaults:偏好设置数据存到沙盒的Library/Preferences目录(实质是plist);
- Write写入形式: 永恒保留在磁盘中;
- 采纳SQLite等数据库来存储数据。
1.NSKeyedArchiver:(归档)
采纳归档的模式来保留数据,该数据对象须要恪守NSCoding协定,并且该对象对应的类必须提供encodeWithCoder:和initWithCoder:办法。
前一个办法通知零碎怎么对对象进行编码,而后一个办法则是通知零碎怎么对对象进行解码。
毛病:
归档的模式来保留数据,只能一次性归档保留以及一次性解压。所以只能针对小量数据,而且对数据操作比拟蠢笨,即如果想改变数据的某一小部分,还是须要解压整个数据或者归档整个数据。
注: initWithCoder什么时候须要调用[super initWithCoder:]
• initWithCoder原理:只有解析文件就会调用,xib,storyboard都是文件,因而只有解析这两个文件,就会调用initWithCoder。• 因而如果在storyboard应用自定义view,重写initWithCoder办法,肯定要调用[super initWithCoder:],因为只有零碎才晓得怎么解析storyboard,如果没有调用,就解析不了这个文件。
2.NSUserDefaults:(偏好设置,实质是plist)
用来保留应用程序设置和属性、用户保留的数据。用户再次关上程序或开机后这些数据依然存在。
NSUserDefaults能够存储的数据类型包含:NSData、NSString、NSNumber、NSDate、NSArray、NSDictionary。如果要存储其余类型,则须要转换为后面的类型,能力用NSUserDefaults存储。
- 益处:1.不须要关怀文件名
2.疾速做键值对存储 - 害处: 能及时存储,须要做同步操作,把内存中的数据同步到硬盘上
底层:就是封装了一个字典
- 沙盒构造剖析:
- 利用程序包:蕴含了所有的资源文件和可执行文件。
- Documents:保留利用运行时成成的须要长久化的数据,iTunes同步设施时会备份该目录。(例如,游戏利用可将游戏存到保留在该目录。大型数据不能寄存在这里,一旦寄存,iOS审核不会通过)
- tmp:保留利用运行时所需的长期数据,应用结束后再将相应的文件从该目录删除。利用没有运行时,零碎也可能会革除该目录下的文件。iTunes同步设施时不会备份该目录。
- Library/Caches:保留利用运行时生成的须要长久化的数据,iTunes同步设施时不会备份该目录。个别存储体积大、不须要备份的非重要数据。(个别把缓存下载好的文件放在这里)
- Library/Preference:保留利用的所有偏好设置,iOS的settings(设置)利用会在该目录中查找利用的设置信息。iTunes同步设施会备份该目录。
注:在iOS7之前,默认不会马上跟硬盘同步,能够调用[userDefaults synchronize]; 同步操作
3. Write写入形式:永恒保留在磁盘中。
4. 采纳数据库来存储数据。
4.1 SQLite
SQLite (http://www.sqlite.org/docs.html) 是一个轻量级的关系数据库。iOS SDK很早就反对了SQLite,在应用时,只须要退出 libsqlite3.dylib 依赖以及引入 sqlite3.h 头文件即可。然而,原生的SQLite API在应用上相当不敌对,在应用时,十分不便。
4.2 FMDB
- 什么是FMDB
FMDB是iOS平台的SQLite数据库框架
FMDB以OC的形式封装了SQLite的C语言API - FMDB的长处
应用起来更加面向对象,省去了很多麻烦、冗余的C语言代码
比照苹果自带的Core Data框架,更加轻量级和灵便
提供了多线程平安的数据库操作方法,无效地避免数据凌乱 - FMDB有三个次要的类
- FMDatabase
一个FMDatabase对象就代表一个独自的SQLite数据库
用来执行SQL语句 - FMResultSet
应用FMDatabase执行查问后的后果集 - FMDatabaseQueue
用于在多线程中执行多个查问或更新,它是线程平安的
通过指定SQLite数据库文件门路来创立FMDatabase对象
//取得数据库文件门路 NSString *doc=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];NSString *fileName=[doc stringByAppendingPathComponent:@"user.sqlite"]; FMDatabase *db = [FMDatabase databaseWithPath:path];if (![db open]) { NSLog(@"数据库关上失败!");}
执行更新
在FMDB中,除查问以外的所有操作,都称为“更新”
create、drop、insert、update、delete等
应用executeUpdate:办法执行更新- (BOOL)executeUpdate:(NSString*)sql, ...- (BOOL)executeUpdateWithFormat:(NSString*)format, ...- (BOOL)executeUpdate:(NSString*)sql withArgumentsInArray:(NSArray *)arguments//示例[db executeUpdate:@"UPDATE t_user SET age = ? WHERE name = ?;", @20, @"Jack"]
执行查问
查询方法- (FMResultSet *)executeQuery:(NSString*)sql, ...- (FMResultSet *)executeQueryWithFormat:(NSString*)format, ...- (FMResultSet *)executeQuery:(NSString *)sql withArgumentsInArray:(NSArray *)arguments示例// 查问数据FMResultSet *rs = [db executeQuery:@"SELECT * FROM t_user"];// 遍历后果集while ([rs next]) { NSString *name = [rs stringForColumn:@"name"]; int age = [rs intForColumn:@"age"]; NSString *sex = [rs doubleForColumn:@"sex"];}
应用FMDatabaseQueue
线程平安:在多个线程中同时应用一个FMDatabase实例是不明智的。当初你能够为每个线程创立一个FMDatabase对象。 不要让多个线程分享同一个实例,它无奈在多个线程中同时应用。 若此,程序会时不时解体,或者报告异样,让人解体。所以,不要初始化FMDatabase对象,而后在多个线程中应用。
请应用 FMDatabaseQueue。以下是应用办法:
//首先创立队列。FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:aPath];//这样应用。[queue inDatabase:^(FMDatabase *db) {[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:1]];[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:2]];[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:3]];FMResultSet *rs = [db executeQuery:@"select * from foo"];while([rs next]) { … }}];//像这样,轻松地把简略工作包装到事务里:[queue inTransaction:^(FMDatabase *db, BOOL *rollback) {[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:1]];[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:2]];[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:3]];if (whoopsSomethingWrongHappened) { *rollback = YES; return; }// etc… [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:4]]; }];
FMDatabaseQueue 后盾会建设系列化的G-C-D队列,并执行你传给G-C-D队列的块。这意味着 你从多线程同时调用调用办法,GDC也会按它接管的块的程序来执行。
4.3 Realm
在挪动畛域,SQLite数据库始终占据着不可撼动的位置。SQLite的缔造者遵循小而精的理念,应用极少量的C代码实现了关系型数据库的外围逻辑。然而,当关系型数据库遇到了面向对象编程语言时,一个困扰着程序员们的难题呈现了。为了实现关系型数据到对象的转换,咱们须要应用SQL语句查问到相应的值。而后,再给对象赋值。这些反复的工作给编码带来了一些麻烦,为了解决这个难题,ORM框架呈现了
ORM (Object Relational Mapping)
ORM框架防止了你间接应用SQL语句进行查问。而是间接应用面向对象的形式帮忙你实现数据的查问,并且主动映射到相应的对象中。这对于一些受够了繁琐SQL语句编写的程序员来说,几乎就是救星。
其实,Realm仍然是关系型数据库的ORM解决方案,比拟不堪设想的是:Realm在增删改查操作中速度简直都优于SQLite,或者靠近SQLite。同样是ORM框架,为什么Realm能够领有如此惊人的速度呢?
答案是:Realm的底层实现根本采纳C++, 原生反对面向对象查问。同时进行了大量的优化,才终于领有了和SQLite一样的性能。
性能方面的担心不必思考了,便开始查看官网文档,Realm的官网文档也十分具体,甚至还有中文版本。
对于挪动端数据库,上面几个方面是不得不思考的:
1)数据库版本的降级
2)是否欠缺的内部调试工具
3)简单查问是否反对
Realm官网文档下面,有对这三个问题的具体解答,上面我来简略论述一下:
第一个问题,Realm提供了Migration类实现对Realm数据库版本的降级保护。
第二个问题,Realm提供了Realm Browser的mac版本,不便在Mac机器下面进行调试。不过,遗憾的是,相干工具并没有提供Windows版本,lol 。
第三个问题,Realm有相干章节,专门介绍了多表查询方法,以及一对多,多对多数据表解决方案。
4.4 CoreData
什么是CoreData?
- Core Data是iOS5之后才呈现的一个框架,它提供了对象-关系映射(ORM)的性能,即可能将OC对象转化成数据,保留在SQLite数据库文件中,也可能将保留在数据库中的数据还原成OC对象。在此数据操作期间,咱们不须要编写任何SQL语句
- CoreData 不能执行SQL语句 取而代之,操作的是对象。而罕用的三方库 FMDB SQLite 能够间接SQL语句
CoreData和数据库有什么区别?
CoreData是一个苹果原生的框架,它领有像数据库一样存储数据的性能,但自身并不是数据库
- Core Data 是iOS SDK 里的一个很弱小的框架,容许程序员以面向对象的形式贮存和管 理数据。应用Core Data 框架,程序员能够很轻松无效地通过面向对象的接口治理数据,所以说CoreData不是数据库,不要以数据库的眼光对待.
Core Data 不是应用程序的数据库,也不是将数据长久化保留到数据库的API。Core Data 是一个 用于治理对象图的框架。Core Data 能够把对象图写入磁盘从而长久化保留
CoreData有什么特点?
(1)CoreData提供了模型层的技术,能够间接对OC对象进行数据长久化
- Core Data 是一个模型层的技术。帮忙建设代表程序状态的模型层,Core Data 也是一种 长久化技术,能将模型对象的状态长久化到磁盘,但它最重要的特点是:Core Data 不仅是 一个加载、保留数据的框架,它还能和内存中的数据很好的共事
- (2)在数据的存储操作过程中,CoreData无需编写任何SQL语句
- (3)Core Data 应用包含实体和实体间关系,以及查找合乎某些条件实体的申请等内容
- (4)开发者能够在纯对象层上查找与治理这些数据,而不用放心存储和查找的实现细节
- (5)Core Data 框架最早呈现在Mac OS X 10.4 Tiger 与iOS 3.0 零碎,通过成千上万的应 用程序以及数以百万用户的重复的验证,Core Data 的确曾经是一套十分成熟的框架
- (6)CoreData 利用了Objective-C 语言和运行时,奇妙地集成了Core Foundation 框架。是 一个易于应用的框架,不仅能够优雅地治理对象图,而且在内存治理方面体现异样优异
CoreData原理:
- 第一眼看到Core Data 令人生畏的简单架构关系,很多人都会有无从下手的感觉
- 可是,一旦了解了架构图中各个部件的组成及相互之间的关系,就能领会到Core Data API 的简 洁和直观了
Core Data stack(技术堆栈):如果可能了解Core Data stack 中的各个成员所表演的角色,那么再 应用Core Data 就不会感觉到艰难了
1.1-什么是CoreData Stack?
Core Data stack 是Core Data 的外围,由一组Core Data 外围对象组成
- NSManagedObjectContext 对象治理上下文: 负责管理模型的对象的汇合
- NSManagedObjectModel 被治理的对象模型: 负责管理对象模型
- NSPersistentStoreCoordinator 存储调度器: 负责将数据保留到磁盘的
1.2-CoreData Stack中的对象是如何协调工作的呢?
组成可分为两局部
- 对象图治理:次要是指对象治理上下文(NSManagedObjectContext)通过对对象模型(NSManagedObjectModel)施行对象治理.
数据长久化:次要是指存储器(NSPersistentStore)来操作SQLite数据库,将数据存储在磁盘中(这部分是零碎帮咱们实现不须要咱们管).
- 在这两局部的两头,即堆栈两头,是长久化存储协调器(Persistent Store Coordinator, PSC)。通过它将对 象图治理局部和长久化局部绑在一起。当这两局部中的一部分须要和另一部分交互,将通过PSC 来 调节
- 其中的留神点:
- 一个工程能够有多个治理模型的Context,一个存储调度器能够调度多个存储器,不过在个别的开发中,咱们只须要一个Contect和一个存储器就足够了