再次学习Core Data

简单的说,Core Data就是可以存储到磁盘的对象图,Core Data可以帮我们做很多任务作。它可以作为软件的整个模型层。它不仅仅在磁盘上存储数据,也把我们需要的数据对象读取到内存中。

http://zh.wikipedia.org/wiki/Core_Data#cite_note-Zarra2009-1

它允许按照实体-属性-值模型组织数据,并以XML,二进制文件或SQLite数据文件的格式将其串行化。Core Data允许用户使用代表实体和实体间关系的高层对象来操作数据。它也可以管理串行化的数据,提供对象生存期管理与object graph管理,包括存储。Core Data直接与SQLite交互,避免开发者使用原本的SQL语句。

使用方法

Core Data使用包括实体和实体间关系,以及查找符合某些条件的实体的请求等内容的高层数据模型描述数据。开发者可以在纯对象层上查找与管理这些数据,二不必担心存储和查找的实现细节。Interface Builder中的控制器对象可以直接获取与管理实体,若与Cocoa绑定结合,则可以在不写自定义代码的情况下让用户界面显示、修改与管理数据模型中的大部分内容。

例如:开发者希望开发一个管理vCard的程序。作者希望使用Core Data将一些vCard读入对象中,然后把它们存入一个大XML文件中。开发者需要在Xcode中创建数据模型,然后到Interface Builder中加入Core Data Entity项以创建其数据模型对应的GUI。然后,开发者可以加入标准的Objective-C代码以读取vCard,并将数据写入由Core Data管理的实体中。在此, 开发者的代码是管理Core Data对象,而非其对应的vCard。最后,将Save菜单项连接到控制器对象对应的方法上,使得控制器在接到存储消息后自动的检查数据堆栈,确认数据是否合法,最后利用当前更改重写对应的Core Data文档。在整个过程中,开发者只需要专注于将vCard文件转换为Core Data实体的过程,而不需关心例如数据的显示、合法性检查、存储等其它部分,提高了开发效率。


类名 用途 关键方法
NSManagedObject
  • 数据对象
  • 管理属性
  • -entity
  • -valueForKey:
  • -setValue: forKey:
NSManagedObjectContext
  • 数据库
  • 获取与存储
  • -executeFetchRequest: error:
  • -save
NSManagedObjectModel
  • 数据模型
  • -entities
  • -fetchRequestTemplateForName:
  • -setFetchRequestTemplate: forName:
NSFetchRequest
  • 请求数据
  • -setEntity:
  • -setPredicate:
  • -setFetchBatchSize:
NSPersistentStoreCoordinator
  • 中介
  • 存储数据
  • -addPersistentStoreWithType: configuration: URL: options: error:
  • -persistentStoreForURL:
NSPredicate
  • 确定查询条件
  • +predicateWithFormat:
  • -evaluateWithObject:

存储格式

Core Data可以将数据存储为XML,二进制文件或SQLite文件。

Core Data是标准化的,可以自由的读写Xcode数据模型文件(通常是.xcdatamodel文件)。


1. Core Data 功能初窥

http://www.cocoachina.com/iphonedev/sdk/2010/1126/2397.html

有时,你可能想要把这样的对象图转化形式,让它们可以被保存到文件中,以使其他的进程或其他的机器可以再次将保存的内容读出,重购对象。 这样的过程常被成之为“归档”(Archiving)。

有些对象图是不完整的——通常称之为局部对象图(partial object graphs)。局部对象图包含了“占位符”(Placeholder)对象,所谓”占位符“,就是一些暂时无内容的对象,它们将再后期被具体化。一个典型的例子就是nib文件中包含的File's Owner对象。

2. 为何要使用Core Data

最简单的一条就是:它能让你为Model层写的代码的行数减少为原来的50%到70%。

除了Core Data本身的优点之外,使用它还有其他的好处: 它很容易和Mac OS X系统的Tool chain集成;利用Model设计工具可以按图形化方式轻松创建数据库的结构;你可以用Instruments的相关模板来测试Core Data的效率并debug。 在Mac OS X的桌面程序中,Core Data还和Interface Builder集成(打开Inspector可以看到有binding的选项,这个东东iPhone上木有。。。),按照model来创建UI变的更简单了。 这些功能能更进一步的帮助你缩短设计、开发、测试程序的周期。

3. Core Data基本架构

使用Core Data的框架,大多数的功能都可以自动实现,因为我们有managed object context(管理对象的上下文,有时直接叫"Context")。managed object context就像是一个关卡,通过它可以访问框架底层的对象——这些对象的集合我们称之为"persistence stack"(数据持久栈)。 managed object context作为程序中对象和外部的数据存储的中转站。栈的底部是persistence object stores(持久化数据存储)。


在调试中出现如下错误,添加委托代码可解决。

'NSInvalidArgumentException', reason: '+entityForName: nil is not a legal NSManagedObjectContext parameter searching for entity name 'Events''

    id delegate = [[UIApplication sharedApplication] delegate];
    self.managedObjectContext = [delegate managedObjectContext];


下面简单说一下做的demo

coredata结构如图


其中appdelegate.h和appdelegate.m中的东西都会在勾选use core data后自动生成。只贴.h代码

#import 

@interface AppDelegate : UIResponder 

@property (strong, nonatomic) UIWindow *window;

//数据对象上下文
@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
//数据模型对象
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
//永久性存储
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;

@property (strong, nonatomic) NSFetchedResultsController *fetchedResultsController;

- (void)saveContext;
- (NSURL *)applicationDocumentsDirectory;

@end

MasterViewController.h

#import 

#import 

#import "AppDelegate.h"

#import "Event.h"

@interface MasterViewController : UIViewController {
    Event *newManagedObject;
}


@property (strong,nonatomic) NSArray *entries;

@property (retain, nonatomic) IBOutlet UITextField *titleTextField;
@property (retain, nonatomic) IBOutlet UITextField *contentTextField;

@property (strong, nonatomic) NSFetchedResultsController *fetchedResultsController;
@property (strong, nonatomic) NSManagedObjectContext *managedObjectContext;

//单击按钮后执行数据保存操作
- (IBAction)addToDB:(id)sender;

//单击按钮后执行查询操作
- (IBAction)queryFromDB:(id)sender;

//当通过键盘在UITextField中输入完毕后,点击屏幕空白区域关闭键盘的操作
-(IBAction)backgroundTapped:(id)sender;

//删除数据
-(IBAction)deleteEntry;

@end

MasterViewController.m

最重要的是给委托。在viewdidload中添加两行代码即可

    id delegate = [[UIApplication sharedApplication] delegate];
    self.managedObjectContext = [delegate managedObjectContext];

数据保存方法

//单击按钮后执行数据保存操作
- (IBAction)addToDB:(id)sender {
    //让CoreData在上下文中创建一个新对象(托管对象)
    newManagedObject = [NSEntityDescription insertNewObjectForEntityForName:@"Event" inManagedObjectContext:managedObjectContext];
    newManagedObject.title=titleTextField.text;
    newManagedObject.body=contentTextField.text;
    newManagedObject.creationDate=[NSDate date];
    
    NSError *error;
    
    //托管对象准备好后,调用托管对象上下文的save方法将数据写入数据库
    BOOL isSaveSuccess = [managedObjectContext save:&error];
    
    if (!isSaveSuccess) {
        NSLog(@"Error: %@,%@",error,[error userInfo]);
    }else {
        NSLog(@"Save successful!");
    }   
}

查询数据方法
//单击按钮后执行查询操作
- (IBAction)queryFromDB:(id)sender {
    //创建取回数据请求
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    //设置要检索哪种类型的实体对象
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event"inManagedObjectContext:self.managedObjectContext];
    //设置请求实体
    [request setEntity:entity];
    //指定对结果的排序方式
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"creationDate"ascending:NO];
    NSArray *sortDescriptions = [[NSArray alloc]initWithObjects:sortDescriptor, nil];
    [request setSortDescriptors:sortDescriptions];
    [sortDescriptions release];
    [sortDescriptor release];
    
    NSError *error = nil;
    //执行获取数据请求,返回数组
    NSMutableArray *mutableFetchResult = [[self.managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
    if (mutableFetchResult == nil) {
        NSLog(@"Error: %@,%@",error,[error userInfo]);
    }
    self.entries = mutableFetchResult;
    
    NSLog(@"The count of entry:%i",[self.entries count]);
    
    for (Event *entry in self.entries) {
        NSLog(@"Title:%@---Content:%@---Date:%@",entry.title,entry.body,entry.creationDate);
    }
    
    [mutableFetchResult release];
    [request release];
}

删除数据方法

用Event *entry in self.entries获得managedObject实体。可以整个删除或者遍历删除。

//删除操作
-(IBAction)deleteEntry
{
    //创建取回数据请求
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    //设置要检索哪种类型的实体对象
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event"inManagedObjectContext:self.managedObjectContext];
    //设置请求实体
    [request setEntity:entity];
    //指定对结果的排序方式
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"creationDate"ascending:NO];
    NSArray *sortDescriptions = [[NSArray alloc]initWithObjects:sortDescriptor, nil];
    [request setSortDescriptors:sortDescriptions];
    [sortDescriptions release];
    [sortDescriptor release];
    
    NSError *error = nil;
    //执行获取数据请求,返回数组
    NSMutableArray *mutableFetchResult = [[self.managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
    if (mutableFetchResult == nil) {
        NSLog(@"Error: %@,%@",error,[error userInfo]);
    }
    self.entries = mutableFetchResult;

    for (Event *entry in self.entries) {
            [managedObjectContext deleteObject:entry];
    }
//    Event *last =[mutableFetchResult lastObject];
//    [managedObjectContext deleteObject:last];
    [mutableFetchResult release];
    [request release];
}

参考
http://blog.csdn.net/tangren03/article/details/7794226

demo下载

http://download.csdn.net/detail/gwh111/5184190

你可能感兴趣的:(ios学习之路)