恩,用Core Data也有一段时间了。大大小小的坑也都坑过了。重来没有认真的记录一次。这次需要好好的理一理Core Data。就当一次绝好的机会记录下来。也为了自己加深认识。

为什么要用Core Data

CoreData的学习是需要一定成本的。以至于我认识的人很少在用,大家要不就是用一个FMDB。或者做的App是一个已有的Web的延伸,数据直接用Web端的Api取回来就好了。

我们要用Core Data的理由有以下几点:

  1. Core Data是对底层存储的一次封装。封装了以后就变成ORM的框架。这样就变成操作对象。Core Data自己去进行数据的保存。

  2. 使用Core Data而不是FMDB,让整个程序架构更加的面向对象。

  3. Core Data仅仅使用了Objective-C和Core Foundation,你不必去加入一些第三方的库。

  4. Core Data是Apple的原生技术。每年的WWDC都能看到新特性的加入和讲授。

  5. Core Data支持iCloud。而使用iCloud的App。Apple推荐的可能性增加。

  6. 有了iCloud为以后Apple的全平台数据共享打下基础

所以,没有理由拒绝使用Core Data做为你App的持久化。Core Data应该是一个跟Apple混的第一选择。

存储原理

NSManagedObjectModel

认识

我个人是把NSManagedObjectModel看做为一个core data的schema。生成这个类的来源是xCode中的Data Model

点击之后会生成一个.xcdatamodeld的文件夹里面的数据具体是是用xml来存储的。
但是你在xCode里面看这个.xcdatamodeld文件夹是认为一个文件。然后可以用xCode来进行图形化的编辑。

如这样

当然还有另外一种表格的方式来编辑Data Model

我们编辑这个的这个文件,理论上来说只是一个资源文件。相当于数据库的schema。我们的数据库长什么样子,就是你来设计的。然后在程序中通过NSURL找到这个资源文件的位置。就可以初始化成为NSManagedObjectModel。

代码加载Data Model

当我们设计好我们的Data Model以后。可以用以下代码,把Data Model加载到NSManagedObjectModel里面去。

1
2
3
4
5
6
7
- (void)initializeCoreDataStack
{
    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"PPRecipes" withExtension:@"momd"];
    ZAssert(modelURL, @"Failed to find model URL");
    NSManagedObjectModel *mom = nil;
    mom = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]; ZAssert(mom, @"Failed to initialize model");
}

NSPersistentStoreCoordinator这样我们就从main bundle里面把data model加载到NSManagedObjectModel这个类里面去了。

NSPersistentStoreCoordinator是整个Core Data的核心。因为承担着全部数据的持久化,加载数据,缓存数据的工作。可以看做Core Data的心脏。

值得我们开心的事情是,虽然NSPersistentStoreCoordinator很重要,但是我们在写程序的时候其实只用初始化和设置一些很简单的参数就可以使用了。在我们App的整个生命周期里面其实并不会很频繁的使用到它。

初始化NSPersistentStoreCoordinator

初始化NSPersistentStoreCoordinator分为两个步骤

  1. 用已经初始化好的NSManagedObjectModel去初始化它

  2. 选择NSPersistentStore为存储的方式

NSPersistentStore

理论上来说NSPersistentStoreCoordinator的数据不一定要存到硬盘上,它可以存到内存里,可以存到网络上。不过都肯定是对应着不同的应用场景。所以我们一般情况还是把它存储到磁盘上。 NSPersistentStore就是用来描述我们要把数据存到哪里的类。NSPersistentStore还可以指定存储数据的文件的文件类型。

目前知道的NSPersistentStore支持三种类型:

  1. SQLite

  2. 二进制

  3. XML

我就只使用SQLite。理论上来说,NSPersistentStore不管选择什么样的存储文件。你后面进行Core Data的操作都是一样的。并不需要修改你的逻辑代码。这就是Core Data把底层封装了一次的好处。(书上说iOS上不建议使用XML)

有一点需要注意的是NSPersistentStoreCoordinator可以加入不止一个的NSPersistentStore。这个在某些特定场景还是很有用的,以后如果能写到在写把。

代码加载NSPersistentStoreCoordinator
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  dispatch_queue_t queue = NULL;
    queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);    dispatch_async(queue, ^{        NSFileManager *fileManager = [NSFileManager defaultManager];        NSArray *directoryArray = [fileManager URLsForDirectory:NSDocumentDirectory
                                                      inDomains:NSUserDomainMask];        NSURL *storeURL = nil;
        storeURL = [directoryArray lastObject];
        storeURL = [storeURL URLByAppendingPathComponent:@"PPRecipes.sqlite"];        NSError *error = nil;
        NSPersistentStore *store = nil;
        store = [psc addPersistentStoreWithType:NSSQLiteStoreType
                               configuration   :nil
                               URL             :storeURL
                               options         :nil
                               error           :&error];        if (!store) {
            ALog(@"Error adding persistent store to coordinator %@\n%@",
                 [error localizedDescription], [error userInfo]);
        }
    });

由于这个过程是一个比较耗费资源的过程。所以我们应该把它放到后台线程里面去做。

1
2
NSFileManager *fileManager = [NSFileManager defaultManager];        NSArray *directoryArray = [fileManager URLsForDirectory:NSDocumentDirectory
                                                      inDomains:NSUserDomainMask];

Apple中不管是OS X还是iOS能上架的App,都是沙箱机制。这个可以自己Goolge看相关的资料。这样的话每一个App都有自己的文件系统。这两句也比较常使用。就是可以获得自己沙箱中的Document文件夹路经。参数的信息直接查文档把。由于这个过程是一个比较耗费资源的过程。所以我们应该把它放到后台线程里面去做。

接下来很重要的一句是

1
2
3
4
5
store = [psc addPersistentStoreWithType:NSSQLiteStoreType
                        configuration   :nil
                        URL             :storeURL
                        options         :nil
                         error           :&error];

第二个参数比较高级。我还没有用到过。文档上写的是设置为nil的时候是把NSPersistentStoreCoordinator作为默认的配置,如果是其他参数可能是把NSPersistentStoreCoordinator设置为其他的用途。此函数的第一个参数是指定NSPersistentStore的存储类型,我们之前说过的三种类型之一。NSSQLiteStoreType就代表这SQLite文件类型。

第三个参数就是我们要存储文件的位置。刚刚我们不是获得的沙箱里面的Document文件夹路经了么。然后我们把文件名加入拼为了一个文件的完整路经传入。

第四个参数类型是一个字典,我们可以传入不同的参数来指定这个NSPersistentStore的类型。比如在本地比如在iCloud。比较高级先为nil。

最后一个参数,为error,传入一个error指针。如果NSPersistentStore初始化失败我们可以获得相应信息。

NSManagedObjectContext

NSManagedObjectContext是我们很经常使用到的一个类。对于为什么要有这个类我个人理解是这样的,在我有限的数据库知识中记得,IO操作是很费时的,因此数据库一般情况是把一系列的操作缓存到了一个内存区域,等待合适的实际在去写入真实的磁盘中。这样大大的提高效率。如果你插入一条数据,然后修改数据,最后删除掉这条数据。如果是每次都执行Commit的话是操作三次IO,如果我们把这三条合并在一起commit的话。是任何事情都不必做。这样能有效的提高整个系统的效率。我认为NSManagedObjectContext的作用在于跟持久化直接做了这层缓存。我们使用Core Data。

还有一点需要注意的是NSManagedObjectContext并不是线程安全的。

关于NSManagedObjectContext的线程安全和高级解释,这里有两篇blog写的超好。

可以一看

Multi-Context CoreData

Zarra on Locking

初级应用的话只用记住一个就ok了NSManagedObjectContext是有一个NSManagedObjectContextConcurrencyType的属性。如果我们是UI操作(主线程操作)我们应该把它设置为NSMainQueueConcurrencyType类型的。

代码加载NSManagedObjectContext

1
2
3
4
5
NSManagedObjectContext                  *moc = nil;
NSManagedObjectContextConcurrencyType   ccType = NSMainQueueConcurrencyType;
moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:ccType];
[moc setPersistentStoreCoordinator:psc];
[self setManagedObjectContext:moc];

总结

至此,三个Core Data的核心类就已经简单说完了一次。他们的关系在上面的图片中表示的很清楚的样子。

NSPersistentStoreCoordinator从NSManagedObjectModel得到模型然后选择NSPersistentStore作为持久化目的地。然后NSManagedObjectContext在作为NSPersistentStoreCoordinator的一个缓存区给我们操作。

当然我这篇blog和接下来准备写的Core Data的可能不会是有完整代码和具体实例的文章。可能只是我对Core Data使用上的一些感悟和梳理。

Core Data (一)备的更多相关文章

  1. Core Data (二)备

    序 上次只是说了三个Core Data栈基本类.这次准备介绍一下常用的类. NSManagedObject Core Data是一次底层数据封装成面向对象的技术.最直接的表现就是在SQLite里面的一 ...

  2. Core Data的使用(二)备

    一.基础概念深入 1.NSManagedObjectContext 被管理数据上下文就像便笺簿 当从数据持久层获取数据时,相当于把这些临时的数据拷贝写在便笺簿上,然后就可以随心所欲的修改这些值. 通过 ...

  3. 使用Core Data应避免的十个错误

    原文:Avoiding Ten Big Mistakes iOS Developers Make with Core Data   http://www.cocoachina.com/applenew ...

  4. iOS开发过程中使用Core Data应避免的十个错误

    原文出处: informit   译文出处:cocoachina Core Data是苹果针对Mac和iOS平台开发的一个框架,主要用来储存数据.对很多开发者来说,Core Data比较容易入手,但很 ...

  5. iOS之Core Data及其线程安全

    一.简介 Core Data是iOS5之后才出现的一个框架,它提供了对象-关系映射(ORM)的功能,即能够将OC对象转化成数据,保存在SQLite数据库文件中,也能够将保存在数据库中的数据还原成OC对 ...

  6. Core Data的一些常见用法

    一.简介 Core Data是一个纯粹的面向对象框架,其本质就是一个ORM(对象关系映射:Object Relational Mapping),能以面向对象的方式操作SQLite数据库.在实际开发中绝 ...

  7. Core Data 使用映射模型

    Core Data 使用映射模型 如果新版本的模型存在较复杂的更改,可以创建一个映射模型,通过该模型指定源模型如何映射到目标模型. 创建映射模型,新建File,  Core Data 选择Mappin ...

  8. SELF, self in CORE DATA

    Predicate SELF Represents the object being evaluated. CORE DATA Retrieving Specific Objects If your ...

  9. Core Data浅谈初级入门

    Core Data是iOS5之后才出现的一个框架,它提供了对象-关系映射(ORM)的功能,即能够将OC对象转化成数据,保存在SQLite数据库文件中,也能够将保存在数据库中的数据还原成OC对象.在此数 ...

随机推荐

  1. 手绘经典QQ头像 请让我一个人呆一会

                                    

  2. cf D. Pair of Numbers

    http://codeforces.com/contest/359/problem/D 题意:给你n个数,然后找出在[l,r]中有一个数a[j],l<=j<=r,在[l,r]中的所有数都是 ...

  3. c指针点滴4-指针的值

    #include <stdio.h> #include <stdlib.h> void main() { ; int *p = &num; //double *p1 = ...

  4. 学完 JAVA SE后学什么 。。。

    我觉得学习j2ee一定要循序渐进,千万不要太急了.把java基础打牢一点,再牢一点.各位,你们在后面学习什么 struts,hibernate,spring,ajax..都很轻松. 第一个阶段(jav ...

  5. java_IO流小结

    字符流和字节流的主要区别: 1.字节流读取的时候,读到一个字节就返回一个字节:  字符流使用了字节流读到一个或多个字节(中文对应的字节数是两个,在UTF-8码表中是3个字节)时.先去查指定的编码表,将 ...

  6. MapReduce新版客户端API源码分析

    使用MapReduce新版客户端API提交MapReduce Job需要使用 org.apache.hadoop.mapreduce.Job 类.JavaDoc给出以下使用范例. // Create ...

  7. first day for new job

    第一天上班,做个总结. 总得来说,感觉非常不错,一个结论~保持头脑清醒,好好加油. 今天主要办一些入职手续,拿到了代码,后面几天主要就是熟悉应用的功能.源代码.想好好制定个计划,定日目标. 1.功能结 ...

  8. ZigBee心电传输(二)

    不管怎样,还是在高手的帮助下完成了前面的硬件部分,现在进行ZigBee的心电AD采集和转换.需要把ZigBee重新拾起来. 首先明确下目标和思路吧,目标是将模拟心电信号通过AD转换,变为数字信号,再用 ...

  9. hdu4000 &amp;&amp; hrbust1625

    ikki的数字 Time Limit: 1000 MS Memory Limit: 32768 K Total Submit: 22(12 users) Total Accepted: 9(8 use ...

  10. 普通用户登录PLSQL后提示空白OK对话框错误

    问题描述: 1.普通域账号登录域成员服务器后,打开PLSQL正常,输入用户名密码登录后提示一个空白的OK对话框,点确定后又返回到输入用户密码界面. 2.在CMD窗口下调用SQLPLUS登录数据库时报如 ...