CoreData (NSManagedObjectContext, NSFetchRequest, NSManagedObjectHow does CoreData work?

1, Create a visual mapping (using Xcode tool) between database and objects.
    (Start with New File ... in Xcode, under Resource, choose Data Model to creates a .xcdatamodel file)
2, Create and query for objects using object-oriented API.
3, Access the “columns in the database table” using @propertys on those objects.  

程序中的对象与外部存储的数据之间通过Core Data框架中的一系列对象进行协调,这一系列的对象总的被称为持久存储栈(Persistence stack)。
在栈顶是被管理对象上下文(Managed object context),
而栈底是持久化对象存储层(Persistence object store),
在它们之间就是持久化存储助理(Persistence Store Coordinator)。
CoreData
上面的图中,employees和departments存储在一个文件中,customers和companies存储在另外一个文件中。当你要获取对象的时候,它们从相关的文件中自动获取;当保存时,又被归档到相应的文件中。

被管理对象和被管理对象模型(Managed Object and the Managed Object Model)NSManagedObject
1、被管理对象(Managed Object)必须是NSManagedObject或其子类的实例。 NSManagedObject可用来表示任何实体。
      一个被管理对象拥有一份实体描述的引用。在使用时,它通过实体描述来找到自身的元数据,包括实体名和属性、关系的信息。你也可以继承NSManagedObject来执行额外的操作。
2、被管理对象模型(Managed Object Model)就是程序中对对象、实体描述的概要图。即用IB创建的 .xcdatamodel文件。

被管理对象上下文(Managed Object Context)NSManagedObjectContext
 
NSFetchRequest,相当于select语句。
1、必须包含一个entity(NSEntityDescription的实例),用于指定所要搜索的实体。即“select * from ?”
2、可以包含一个predicate(NSPredicate的实例),用于指定所要搜索实体的属性、搜索条件等。即 “select ? from entity where ? ”
3、可以包含一个sort descriptors数组(NSSortDescriptor的实例),用于指定搜索结果的排列顺序。即“order by ?”
     
CoreData
 
4、示例代码:
 
   
NSFetchRequest * fetchRequest = [[ NSFetchRequest alloc ] init ];
NSEntityDescription * entity = [ NSEntityDescription entityForName :@ "Book" inManagedObjectContext : managedObjectContext ];
[ fetchRequest setEntity : entity ];
NSSortDescriptor * authorDescriptor = [[ NSSortDescriptor alloc ] initWithKey :@ "author" ascending : YES ];
NSSortDescriptor * titleDescriptor = [[ NSSortDescriptor alloc ] initWithKey :@ "title" ascending : YES ];
NSArray * sortDescriptors = [[ NSArray alloc ] initWithObjects : authorDescriptor , titleDescriptor , nil ];
[ fetchRequest setSortDescriptors : sortDescriptors ];

 
 
并非严格的说,CoreData是对sqlite数据库的一个封装。
sqlite数据库操作的基本流程是:创建数据库,通过定义一些字段来定义表格结构,可以利用sql语句向表格中插入记录、删除记录、修改记录、表格之间也可以建立联系。
  这个过程出现了,表格的结构(schema),所有表格的结构和相互联系构成整个数据库的模型,数据库存放的方式(可以是文件或者在内存),数据库操作,sql语句(主要是查询),,表格里面的记录。
  下面将上面说的文字,跟CoreData的类作个对应:
  表格结构    --> NSEntityDescription
  数据库中所有表格和他们的联系 -->NSManagedObjectModel
  数据库存放方式 --> NSPersistentStoreCoordinator
  数据库操作 --> NSManagedObjectContext
  查询语句 --> NSFetchRequest
  表格的记录 --> NSManagedObject
  可能上面的对应关系并非十分严格, 但确实可以帮助理解
  下面再看看CoreData的类
  NSEntityDescription
  NSManagedObjectModel
  NSEntityDescription用来定义表格结构,所以你就可以理解NSManagedObjectModel中的setEntities:(NSArray *)entities函数大概有什么用了。通常,定义model,是用文件CoreData.xcdatamodel,可以图形化的操作,这类似用nib来创建界面。
  建个工程,使用coredata,模拟器运行之后,程序对应的document目录出现一个CoreData.sqlite。可以利用sqlite3命令来查看里面的表格结构。
  用命令行sqlite3 CoreData.sqlite 进入
  >.tables
  ZEVENT        Z_METADATA    Z_PRIMARYKEY
  可以看到有表格ZEVENT,对应的CoreData.xcdatamodel文件有名字叫Event的Entity
  >.schema ZEVENT
  CREATE TABLE ZEVENT ( Z_PK INTEGER PRIMARY KEY, Z_ENT INTEGER, Z_OPT INTEGER, ZTIMESTAMP TIMESTAMP );
  对应的Event中有属性timeStamp,可以看到,相应的ZEVENT表格中有字段TIMESTAMP
  > select * from ZEVENT
  1|1|1|306295807.974966
  2|1|1|306295810.981875
  3|1|1|306295811.982537
  这表格有三个记录,可以用来初始化三个NSManagedObject,修改了NSManagedObject,save之后也修改了表格记录
  你可以在CoreData.xcdatamodel添加新的entity,之后用sqlit3命令来查看数据库的变化。
  NSPersistentStoreCoordinator
  这个类的对象通常用NSManagedObjectModel的对象来初始化,这个类抽象出不同的存放方式,最经常用的是NSSQLiteStoreType。
  NSManagedObjectContext
  这个类的对象又用NSPersistentStoreCoordinator的对象来初始化,它里面有些方法来添加,删除NSManagedObject。
  NSFetchRequest
  通常用NSEntityDescription来构造查询,也就指定查询那个表格,另外可以指定排序。
  在CoreData的设计中, 下一层有相应的属性指向上一层,所以NSManagedObject有属性得到NSEntityDescription,NSEntityDescription有属性得到NSManagedObjectModel。
  至于类
  NSFetchedResultsController,只是又封了一下,和NSFetchRequest合起来使用,方便取数据,另外和NSManagedObjectContext关联,当数据库发生变化的时候收到通知。
  本文只初步梳理了一下CoreData各类的关系,各类的方法还需要一一研究。文章最开始说CoreData是对sqlite数据库的一个封装,不是严格的。CoreData不一定用sqlit来实现,但他们之间确实有种对应关系。

A simple Core Data stack
CoreData