[http://blog.csdn.net/jiangshurunhe/article/details/10304309]

先简单的说一下coredata
coredata的五个模块:
1, Managed Object Model
Managed Object Model 是描述应用程序的数据模型,这个模型包含实体(Entity),特性(Property),读取请求(Fetch Request)等。(下文都使用英文术语。)
应用程序先创建或读取模型文件(后缀为xcdatamodeld)生成 NSManagedObjectModel 对象。Document应用程序是一般是通过 NSDocument 或其子类 NSPersistentDocument)从模型文件(后缀为 xcdatamodeld)读取。

2,Managed Object Context
Managed Object Context 参与对数据进行各种操作的整个过程,它持有 Managed Object。我们通过它来监测 Managed Object。监测数据对象有两个作用:支持 undo/redo 以及数据绑定。这个类是最常被用到的

3,Persistent Store Coordinator
Persistent Store Coordinator 负责从数据文件(xml, sqlite,二进制文件等)中读取数据生成 Managed Object,或保存 Managed Object 写入数据文件,处理底层的对数据文件的读取与写入。一般我们无需与它打交道。

4,Managed Object
Managed Object 数据对象,与 Managed Object Context 相关联。

5,Controller
一般都是通过 control+drag 将 Managed Object Context 绑定到它们,这样我们就可以在 nib 中可视化地操作数据。

模型有点像数据库的表结构,里面包含 Entry, 实体又包含三种 Property:Attribute(属性),RelationShip(关系), Fetched Property(读取属性)。Model class 的名字多以 "Description" 结尾。我们可以看出:模型就是描述数据类型以及其关系的。

主要的 Model class 有:

Model Classes
Managed Object Model NSManagedObjectModel数据模型
Entity NSEntityDescription抽象数据类型,相当于数据库中的表
Property NSPropertyDescriptionEntity 特性,相当于数据库表中的一列
  > Attribute NSAttributeDescription基本数值型属性(如Int16, BOOL, Date等类型的属性)
  > Relationship NSRelationshipDescription属性之间的关系
  > Fetched Property NSFetchedPropertyDescription查询属性(相当于数据库中的查询语句)

1)Entity - NSEntityDescription
Entity 相当于数据库中的一个表,它描述一种抽象数据类型,其对应的类为 NSManagedObject 或其子类。

NSEntityDescription 常用方法:
+insertNewObjectForEntityForName:inManagedObjectContext: 工厂方法,根据给定的 Entity 描述,生成相应的 NSManagedObject 对象,并插入 ManagedObjectContext 中。
-managedObjectClassName 返回映射到 Entity 的 NSManagedObject 类名
-attributesByName 以名字为 key, 返回 Entity 中对应的 Attributes
-relationshipsByName 以名字为 key, 返回 Entity 中对应的 Relationships

2)Property - NSPropertyDescription
Property 为 Entity 的特性,它相当于数据库表中的一列,或者 XML 文件中的 value-key 对中的 key。它可以描述实体数据(Attribute),Entity之间的关系(RelationShip),或查询属性(Fetched Property)。

> Attribute - NSAttributeDescription
Attribute 存储基本数据,如 NSString, NSNumber or NSDate 等。它可以有默认值,也可以使用正则表达式或其他条件对其值进行限定。一个属性可以是 optional 的。
 
 > Relationship - NSRelationshipDescription 
Relationship 描述 Entity,Property 之间的关系,可以是一对一,也可以是一对多的关系。

> Fetched Property - NSFetchedPropertyDescription
Fetched Property 根据查询谓词返回指定 Entity 的符合条件的数据对象。

Managed Object - NSManagedObject
Managed Object 表示数据文件中的一条记录,每一个 Managed Object 在内存中对应 Entity 的一个数据表示。Managed Object 的成员为 Entity 的 Property 所描述。

每一个 Managed Object 都有一个全局 ID(类型为:NSManagedObjectID)。Managed Object 会附加到一个 Managed Object Context,我们可以通过这个全局 ID 在 Managed Object Context 查询对应的 Managed Object。
NSManagedObject 常用方法
-entity 获取其 Entity
-objectID 获取其 Managed Object ID
-valueForKey: 获取指定 Property 的值
-setValue: forKey: 设定指定 Property 的值
> Managed Object Context - NSManagedObjectContext

Managed Object Context 的作用相当重要,对数据对象进行的操作都与它有关。当创建一个数据对象并插入 Managed Object Context 中,Managed Object Context 就开始跟踪这个数据对象的一切变动,并在合适的时候提供对 undo/redo 的支持,或调用 Persistent Store Coordinato 将变化保存到数据文件中去。

通常我们将 controller 类与 Managed Object Context 绑定,这样就方便我们动态地生成,获取数据对象等。
NSManagedObjectContext 常用方法
-save: 将数据对象保存到数据文件
-objectWithID: 查询指定 Managed Object ID 的数据对象
-deleteObject: 将一个数据对象标记为删除,但是要等到 Context 提交更改时才真正删除数据对象
-undo 回滚最后一步操作,这是都 undo/redo 的支持
-lock 加锁,常用于多线程以及创建事务。同类接口还有:-unlock and -tryLock
-rollback 还原数据文件内容
-reset 清除缓存的 Managed Objects。只应当在添加或删除 Persistent Stores 时使用
-undoManager 返回当前 Context 所使用的 NSUndoManager
-assignObject: toPersistantStore: 由于 Context 可以管理从不同数据文件而来的数据对象,
这个接口的作用就是指定数据对象的存储数据文件(通过指定 PersistantStore 实现)
-executeFetchRequest: error: 执行 Fetch Request 并返回所有匹配的数据对象
> Persistent Store Coordinator - NSPersistentStoreCoordinator
使用 Core Data document 类型的应用程序,通常会从磁盘上的数据文中中读取或存储数据,这写底层的读写就由 Persistent Store Coordinator 来处理。一般我们无需与它直接打交道来读写文件,Managed Object Context 在背后已经为我们调用 Persistent Store Coordinator 做了这部分工作。
NSPersistentStoreCoordinator 常用方法
-addPersistentStoreForURL:configuration:URL:options:error:装载数据存储,对应的卸载数据存储的接口为 -removePersistentStore:error:
-migratePersistentStore:toURL:options:withType:error:迁移数据存储,效果与 "save as"相似,但是操作成功后,
迁移前的数据存储不可再使用
-managedObjectIDForURIRepresentation: 返回给定 URL所指示的数据存储的 object id,如果找不到匹配的数据存储则返回 nil
-persistentStoreForURL: 返回指定路径的 Persistent Store
-URLForPersistentStore: 返回指定 Persistent Store 的存储路径
> Persistent Document - NSPersistentDocument
NSPersistentDocument 是 NSDocument 的子类。 multi-document Core Data 应用程序使用它来简化对 Core Data 的操作。通常使用 NSPersistentDocument 的默认实现就足够了,它从 Info.plist 中读取 Document types 信息来决定数据的存储格式(xml,sqlite, binary)。
NSPersistentDocument 常用方法
-managedObjectContext 返回文档的 Managed Object Context,在多文档应用程序中,每个文档都有自己的 Context。
-managedObjectModel 返回文档的 Managed Object Model

用Magical Record,使Core Data获取数据更便捷!

Magic Record是Saul Mora写的一个开源的类库,目的是使得Core Data使用起来更加的便捷容易。这个库的开发灵感来自于Ruby on Rails(Web 应用程序框架)中的active record模式。这个教程将给你讲述如何在你的app应用中使用 Magic Record!

为什么选择Magical Record?如果你已经开发过iOS或者OS X 一段时间了的话,你就有机会尝试一下Core Data 堆栈(stack)了。这意味着你知道建立一个Core Data是相当麻烦的,主要是因为Core Data有冗长的语法所以在使用起来可能会有点复杂。例如,从一个 persistentstore(持久化存储)中获取数据是非常复杂的,尤其是再对比一下Ruby on Rails是如何获取数据的。

向你展示Magic Record最好的方式就是使用这个强大的库来创建一个应用。你将发现使用Magic Record是多么的容易。我们将向你讲述用Core Data和Magic Record来创建项目需要涉及哪些内容。用户可以获取,创建,更新,删除数据的方法。
  既然你已经阅读到了这里,我假定你已经很熟悉iOS的开发,且对Core Data有了一些基本的认识。在这篇文章中,我将主要关注应用的Core Data方向,对代码的其余部分我将不详细赘述。

Step 1: 启动项目
  用Single View Application模板来创建一个项目,把它命名为Magic Notes(随便命名的),设置设备为iPhone, 勾选Use Automatic Reference Counting使ARC能够正常使用。在这篇教程中,我们不使用Storyboards 或者 Unit Tests.

Step 2: 添加Magic Record 
  既然我们在这个项目中使用了Core Data,就不要忘记把Core Data框架链接你的项目中。这是一篇高阶教程,所以在此不赘述如何去做这个工作。
   添加Magic Record库到你的项目中并不需要任何神奇的工作。从GitHub中下载最新的版本,打开 archive,拖拽名为MagicalRecord到你的Xcode项目中,勾选Copy times into destination gout's folder(if needed)选框,以保证复制文件夹的内容到你的项目中,不要忘记勾选Add to target ,也可以用git submodule add,用git工具比较好,更新代码比较简单,一行命令就可以了:git submodule update。你也可以使用CocoaPods(一个用来管理Xcode依赖库的项目)来管理MagicalRecord。
   
   确保可以在你的类中使用Magic Record, 我们需要导入一个头文件,CoreData+MagicRecord.h。在本节教程中使用Magic Record较为频繁,所以更加方便的办法是把这个import语句放到项目的Prefix.pch文件中。这会确保Magic Record可以在你的项目的任何类中访问。
   所有的Magic Record方法都默认带有前缀MR_,你可以在Prefix.pch文件中添加一行#define MR_SHORTHAND的代码来避免写MR_前缀。关键的一点是你必须把这行代码放到import "CoreData+MagicalRecord.h"这行代码的前面。

#ifdef __OBJC__ 
    #import <UIKit/UIKit.h> 
    #import <Foundation/Foundation.h> 
    #define MR_SHORTHAND 
    #import "CoreData+MagicalRecord.h" 
#endif
复制代码

Step 3: 创建一个Core Data Model(被管理对象模型)
  在建立Core Data stack前,我们需要创建一个Core Data Model(new filte --> core data --> data module --> add Entity)。这个项目的Core Data Model非常简单,就一个名为Note的实体。在attributes中加四个属性,date, title, body和keywords,Title, body, 和keywords 的类型为string,而date的类型为date。
  开始创建一个新的Core Data Model,把它命名为MagicalNotes。创建一个Note实体并且添加四个属性作为outlined)。

在我们继续下一步之前,我们还需要为Note实体创建一个自定义的NSManagedObject子类。这是非常有用的,选中对应的Entity, 点击顶部菜单Editor-->Create NSManagedObject SubClass,会自动根据Entity 创建NSManagedObject class。

Step 4: 创建Core Data Stack
   如果你不用提供任何Xcode模板的话,建立Core Data stack将需要大量的工作。但是如果使用了Magic Record,就没那么麻烦了。在application:didFinishLaunchingWithOptions: 应用的一个方法中添加如下的代码片段:
[MagicalRecord setupCoreDataStack];([MagicalRecord setupCoreDataStackWithAutoMigratingSqliteStoreNamed:@"note(项目名).db"];)
   
   这就是所有需要做的了。Magic Record创建store的名字默认跟你项目的名字是一样的。不过你可以调用setupCoreDataStackWithStoreNamed方法来自定义存储的名字:替换和传递store的名字。
   Magical Record 可以在主线程上实例化 managed object context(被管理对象上下文), a persistent store coordinator (持久化存储协调器)and a managed object model(被管理对象模型).
提示:Magical Record 还有一个内置的功能:纪录Core Data信息和错误到console中。第一次构建和运行完你的程序后看下console。console中的日志准确的纪录了Magic Record在后台做了哪些工作。

Step 5: 搭建基础框架
       在我们开始创建新的笔记的时候,我们首先要做一些繁重的工作。重新回顾一下你的应用委托的application:didFinishlaunchingWithOptions方法,用main view controller(主视图控制类)作为root view controller(根视图控制类)来初始化一个navigation controller(导航控制类)。来看一下这个方法的完整实现:
  在main view controller的implementation文件中,添加一个名为sourcesFrc的私有属性到类扩展的顶端。保证属性的类型是NSFetchedResultsController. sourcesFrc属性将会存储那些我们在数据库中获取到的笔记,并且我们将它作为table view的数据来源。
下面是常用的代码:

+ (NSFetchedResultsController *) fetchAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm groupBy:(NSString *)groupingKeyPath delegate:(id<NSFetchedResultsControllerDelegate>)delegate;

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return sourcesFrc.fetchedObjects.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell"; 
    UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
    if (cell == nil) { 
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]; 
        // Configure Cell 
        [cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator]; 
    } 
    // Fetch Note 
    Note *note =  sourcesFrc.fetchedObjects[indexPath.row]; 
    // Configure Cell 
    [cell.textLabel setText:[note title]]; 
    [cell.detailTextLabel setText:[note keywords]]; 
    return cell;
}

#pragma mark - NSFetchedResultsControllerDelegate
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
[self.tableView beginUpdates];
}

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath
{
if (type == NSFetchedResultsChangeInsert) {
[self.tableView insertRowsAtIndexPaths:@[newIndexPath]
 withRowAnimation:UITableViewRowAnimationFade];
} else if (type == NSFetchedResultsChangeDelete) {
[self.tableView deleteRowsAtIndexPaths:@[indexPath]
 withRowAnimation:UITableViewRowAnimationFade];
} else if (type == NSFetchedResultsChangeUpdate) {
[self.tableView reloadRowsAtIndexPaths:@[indexPath]
 withRowAnimation:UITableViewRowAnimationNone];
} else if (type == NSFetchedResultsChangeMove) {
[self.tableView moveRowAtIndexPath:indexPath toIndexPath:newIndexPath];
}
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
[self.tableView endUpdates];
if (!sourcesFrc.fetchedObjects.count) {
  [_tableView reloadData];
}
}

- (void)remove:(JSONCompletionBlock)completion
{
[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {
Source *_source = [self inContext:localContext];
[_source deleteEntity];
}];
}
删除方法: [_note deleteEntity];

- (void)addOneObject
{
[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {
Note *_note = [Note createInContext:localContext];
_note.title = @"test";
}];
}
特别注意一点:module必须是在context中操作,所有的edit/add/都是在context中操作的,一般最好是用NSFetchedResultsController来处理数据,

Magical Record有比我在这篇文章中显示给你的更多的内容。发布2.0版本以来。Magical Record可以处理nested contexts,它提供了对iCloud的支持,和线程处理方面的内容。这篇文章的主要目的是向你展示Core Data并不是很难处理的,Saul Mora 用Magical Record向你表明了这点。

coredata 及 Magical Record相关推荐

  1. 「最简单」的 Core Data 上手指南

    本文讲的是「最简单」的 Core Data 上手指南, 原文地址:The Easiest Core Data 原文作者:Alberto De Bortoli 译文出自:掘金翻译计划 译者:Zheaol ...

  2. Core Data 多线程操作实战篇

    最近在解决百度音乐iPhone客户端偶现数据库操作crash的问题,顺手整理了下CoreData的多线程原则,以及实际开发时应该如何遵守这些原则. Core Data多线程操作的基本原则 不允许跨线程 ...

  3. oc对mysql支持_iOS中数据库使用什么技术实现的

    使用Sqlite和CoreData实现的 常用数据库: SQLServer 2000-保存游戏的素有用户的信息: OracleMySQL-网上PHP网站室友较多,特点是网路数据库,支持的功能多,程序比 ...

  4. MagicalRecord入门教程

    Magical Record是什么 在Cocoa中存在一种技术叫Core Data,用来对数据进行持久化,类似于Java世界中的Hibernate.在新建Cocoa Application/iOS A ...

  5. MagicalRecord

    MagicalRecord 2.1 前言 CoreData是iOS开发中经常使用的数据持久化的技术.但其操作过程稍微繁琐,即使你只是实现简单的存取,不涉及请求优化,也要进行许多配置工作,代码量在动辄几 ...

  6. [翻译] 学习iOS开发的建议:如何从菜鸟到专家

    [文章原地址] http://mobile.tutsplus.com/tutorials/iphone/ios-quick-tip-from-novice-to-expert/ 翻译有误之处请勿见笑, ...

  7. iOS开发用到的强大的开源工具

    英文原文:Things I wish I had known before starting iOS development-Part 2 如果你还没读这篇文章的第一部分,请先读完了再来看第二部分. ...

  8. 学习iOS开发前要知道的事儿

    英文原文:Things I wish I had known before starting iOS development-Part 1 设计师设计出来了一个不错的引导界面,然而当我看到设计稿的时候 ...

  9. 学习iOS开发的建议:如何从菜鸟到专家

    http://mobile.tutsplus.com/tutorials/iphone/ios-quick-tip-from-novice-to-expert/ 翻译有误之处请勿见笑,本人将在文章的部 ...

最新文章

  1. 面试造飞机这么能耐,对着调优实战更不能怂啊!
  2. 数据库基础-数据库引擎
  3. xpath定位中starts-with、contains和text()的用法
  4. Browser Security-同源策略、伪URL的域
  5. Python 技术篇-设置windows开机自动启用Jupyter服务,BAT批处理脚本启用jupyter服务设置,设置jupyter默认启动位置的方法
  6. 趣谈设计模式 | 单例模式(Singleton) :独一无二的对象
  7. 关闭防火墙_从零开始学Linux运维|09.关闭防火墙和SElinux
  8. linux系统备份和恢复
  9. 多段实例代码详解7大类Python运算符,建议收藏!
  10. django调用支付宝
  11. 写作就像升级打怪,4个实战技巧让你“写什么都很棒”!
  12. Postman 汉化包(设置中文)
  13. 【好文随记】牛人大学的感悟
  14. 1024info .php,GitHub - dingusxp/code1024
  15. pth文件转为onnx格式
  16. java vo的使用_使用VO传递参数的设计 | 学步园
  17. 数据分析报告这样写,才算真正读懂了数据
  18. 百度AI 2020年的这份成绩单,让我们看到AI全面进入生活的清晰图景
  19. 什么是CRM、ERP、BPM?
  20. golang及beego框架单元测试小结

热门文章

  1. 阿里云架构师解读四大主流游戏架构
  2. 2021年全球电主轴市场销售额达到了14亿美元,预计2028年将达到21亿美元
  3. 懒散的奶牛(lazy)
  4. 数据仓库-信贷管理系统
  5. 如何学好c语言数据结构编程,如何学好C语言和数据结构,为什么学不好编程?——好文章一网打尽...
  6. TCP三次握手和四次挥手的全过程
  7. C++双人战争游戏(机房娱乐)
  8. 计及源荷不确定性的综合能源生产单元运行调度与容量配置优化研究(Matlab代码实现)
  9. beanstalkd学习笔记
  10. 低温环境对电池的影响