Core Data (一)备
序
恩,用Core Data也有一段时间了。大大小小的坑也都坑过了。重来没有认真的记录一次。这次需要好好的理一理Core Data。就当一次绝好的机会记录下来。也为了自己加深认识。
为什么要用Core Data
CoreData的学习是需要一定成本的。以至于我认识的人很少在用,大家要不就是用一个FMDB。或者做的App是一个已有的Web的延伸,数据直接用Web端的Api取回来就好了。
我们要用Core Data的理由有以下几点:
Core Data是对底层存储的一次封装。封装了以后就变成ORM的框架。这样就变成操作对象。Core Data自己去进行数据的保存。
使用Core Data而不是FMDB,让整个程序架构更加的面向对象。
Core Data仅仅使用了Objective-C和Core Foundation,你不必去加入一些第三方的库。
Core Data是Apple的原生技术。每年的WWDC都能看到新特性的加入和讲授。
Core Data支持iCloud。而使用iCloud的App。Apple推荐的可能性增加。
有了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分为两个步骤
用已经初始化好的NSManagedObjectModel去初始化它
选择NSPersistentStore为存储的方式
NSPersistentStore
理论上来说NSPersistentStoreCoordinator的数据不一定要存到硬盘上,它可以存到内存里,可以存到网络上。不过都肯定是对应着不同的应用场景。所以我们一般情况还是把它存储到磁盘上。 NSPersistentStore就是用来描述我们要把数据存到哪里的类。NSPersistentStore还可以指定存储数据的文件的文件类型。
目前知道的NSPersistentStore支持三种类型:
SQLite
二进制
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写的超好。
可以一看
初级应用的话只用记住一个就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 (一)备的更多相关文章
- Core Data (二)备
序 上次只是说了三个Core Data栈基本类.这次准备介绍一下常用的类. NSManagedObject Core Data是一次底层数据封装成面向对象的技术.最直接的表现就是在SQLite里面的一 ...
- Core Data的使用(二)备
一.基础概念深入 1.NSManagedObjectContext 被管理数据上下文就像便笺簿 当从数据持久层获取数据时,相当于把这些临时的数据拷贝写在便笺簿上,然后就可以随心所欲的修改这些值. 通过 ...
- 使用Core Data应避免的十个错误
原文:Avoiding Ten Big Mistakes iOS Developers Make with Core Data http://www.cocoachina.com/applenew ...
- iOS开发过程中使用Core Data应避免的十个错误
原文出处: informit 译文出处:cocoachina Core Data是苹果针对Mac和iOS平台开发的一个框架,主要用来储存数据.对很多开发者来说,Core Data比较容易入手,但很 ...
- iOS之Core Data及其线程安全
一.简介 Core Data是iOS5之后才出现的一个框架,它提供了对象-关系映射(ORM)的功能,即能够将OC对象转化成数据,保存在SQLite数据库文件中,也能够将保存在数据库中的数据还原成OC对 ...
- Core Data的一些常见用法
一.简介 Core Data是一个纯粹的面向对象框架,其本质就是一个ORM(对象关系映射:Object Relational Mapping),能以面向对象的方式操作SQLite数据库.在实际开发中绝 ...
- Core Data 使用映射模型
Core Data 使用映射模型 如果新版本的模型存在较复杂的更改,可以创建一个映射模型,通过该模型指定源模型如何映射到目标模型. 创建映射模型,新建File, Core Data 选择Mappin ...
- SELF, self in CORE DATA
Predicate SELF Represents the object being evaluated. CORE DATA Retrieving Specific Objects If your ...
- Core Data浅谈初级入门
Core Data是iOS5之后才出现的一个框架,它提供了对象-关系映射(ORM)的功能,即能够将OC对象转化成数据,保存在SQLite数据库文件中,也能够将保存在数据库中的数据还原成OC对象.在此数 ...
随机推荐
- gets和从键盘输入换行符
i was wrong! 虽然setbuf可以让程序自己管理缓冲,但是像getchar,gets这些标准IO函数还是要通过隐藏的stdin进行操作,而stdin是啥呢?还是一个FILE*,而FILE* ...
- Blogger安装最新文章 - Blog透视镜
在Blogger中,是没有最新文章的网页元素,不过倒是有信息提供这个小工具,其实这就是用来新增RSS网摘用的,其中就包含最新文章的Feed,所以只要在小工具中,加入RSS网摘Feed,就可以安装最新文 ...
- xdebug及webgrind的联用
参考URL: http://www.tuicool.com/articles/ERFNva http://blog.sina.com.cn/s/blog_635833b3010127q5.html h ...
- JavaScript中String对象处理HTML标记中文本的方法
big():创建一个<big></big>标记,将这个字符串的字体变大blink():创建一个<blink></blink>标记,使字符串具有闪烁效果b ...
- 利用好CSS,实现Qt控件美化
一.CSS概念 级联样式表 (CSS) 包含应用于网页中的元素的样式规则.CSS 样式定义元素的显示方式以及元素在页中的放置位置.可以创建一个通用规则,只要 Web 浏览器遇到一个元素实例,或遇到一个 ...
- ActionBarActivity & FragmentActivity
1 ActionBarActivity 是FragmentActivity的一个子类 2 ActionBarActivity 加入了对actionBar的操作, 比如getSupportActionB ...
- Excel2010 柱形图与折线图制表
示例1: 数据格式 问题:现在要用柱形图表示手机网民数和年增长率,横轴表示年份,纵轴(1)表示手机网民数,纵轴折线图(2)表示年增长率,要做在一个图表中,请问该怎么做? 步骤: 1.选择A/B/C所在 ...
- C/C++基础概念
1.类占用的内存大小: 1)在不同位数的操作系统下,各种数据类型所占用的内存大小:32位和64位操作系统 http://blog.csdn.net/b_zhang/article/details/68 ...
- JavaScript 获取CSS媒体查询信息
var result = window.matchMedia('(max-width: 700px)'); if (result.matches) { console.log('页面宽度小于等于700 ...
- 【转】Difference between Point-To-Point and Publish/Subscribe JMS Messaging Models
Difference between Point-To-Point and Publish/Subscribe JMS Messaging Models Point-to-Point (PTP) ...