乐趣区

关于objective-c:ObjectiveC之数据存储漫谈

存储形式介绍

  1. NSKeyedArchiver:采纳归档的模式来保留数据沙盒中;
  2. NSUserDefaults:偏好设置数据存到沙盒的 Library/Preferences 目录(实质是 plist);
  3. Write 写入形式:永恒保留在磁盘中;
  4. 采纳 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 有三个次要的类
  1. FMDatabase
    一个 FMDatabase 对象就代表一个独自的 SQLite 数据库
    用来执行 SQL 语句
  2. FMResultSet
    应用 FMDatabase 执行查问后的后果集
  3. 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 和一个存储器就足够了
退出移动版