Core Data的使用

来源:互联网 发布:软件注册权 编辑:程序博客网 时间:2024/05/09 00:19

       初步看了一下Core Data这个东西,本想早一点写这篇东西的,不过各种俗事缠身,又觉得自己对于Core Data机制了解的还不够深,动笔就慢了几天。不过今天盘点一下,觉得可以说一点东西出来就先说一点吧。

      Core Data到底是个什么东西?是不是就是SQLite数据库?我觉得随着应用的越来越复杂,体现出来就是数据之间的关系越来越复杂,访问逻辑也变的更加的复杂臃肿,而相当多的应用都会用到数据的模型(或简单或复杂),所以苹果就单独弄了这样一个概念出现,并提供了辅助编辑/代码生成的工具,可以帮助减少不少工作量。至于说数据库,确实很多时候Core Data都是用数据库来做存储的支撑,但一来并非必须用数据库来存储,二来封装之后不需要任何SQL语句的,所以只能说数据库是支撑Core Data的技术之一,并非等价于Core Data。

      Core Data里面自己定义了一些名词,什么NSManagedObject/NSManagedObjectContext/NSManagedObjectModel,这几个是最混淆的,其他的什么NSFetchRequest/NSEntityDescription还算好一点。(顺便吐槽一句,这种术语的翻译是最成问题的,不少书中还把这些翻成托管对象,托管对象上下文等等的,第一次看的时候你肯定一头雾水)

       既然说到是Data,那么肯定是以数据为核心,同时封装对于数据的操作,形成一系列的辅助类。

       NSManagedObject肯定是核心,这个可以看成一个一个的数据对象的实例,但封装后你很少直接访问这个类

       NSManagedObjectContext是我们实际编程时打交道最多的,要访问一个数据对象,必须通过他的上下文

       NSManagedObjectModel是我们整个应用程序里面的数据的抽象,包括了Entity,Attribute,Request等等

       NSPresistentStoreCoordinator是对于数据存取的封装,封装了具体的加载/存储的实现细节


       下面还是通过代码来看比较清晰,首先来看Xcode用于Core Data的辅助工具

        

        编辑数据类型结束之后,Xcode会自动生成不少代码,其中每个Entity都会实现成一个类,Xcode会自动生成.h和.m文件

        

        这个类实现的很简单,就是把属性列了一下,我们来看一下Event类的代码

@interface Event : NSManagedObject@property (nonatomic, retain) NSDate * creationDate;@property (nonatomic, retain) NSNumber * latitude;@property (nonatomic, retain) NSNumber * longitude;@end
    
@implementation Event@dynamic creationDate;@dynamic latitude;@dynamic longitude;@end

        除了这几个类之外,应用的Delegate也有巨大的改变,ManagedObjectModel/ManagedObjectContext都在这里生成。

@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;- (void)saveContext;- (NSURL *)applicationDocumentsDirectory;

        有了这些之后,我们来看数据的具体操作,假定我们要生成一个Event数据对象,并赋予当前的位置的值,然后存储起来

        Event *event = (Event*)[NSEntityDescription insertNewObjectForEntityForName:@"Event" inManagedObjectContext:self.managedObjectContext];                CLLocationCoordinate2D coordinate = [_location coordinate];        [event setCreationDate:[NSDate date]];        [event setLatitude:[NSNumber numberWithDouble:coordinate.latitude]];        [event setLongitude:[NSNumber numberWithDouble:coordinate.longitude]];                NSError *error = nil;        if (![self.managedObjectContext save:&error]) {            NSLog(@"save new event error! errcode=%d", error.code);        }

        NSEntityDescription类是Entity的描述类,这个类有个全局的工厂方法,

+ (id)insertNewObjectForEntityForName:(NSString *)entityName inManagedObjectContext:(NSManagedObjectContext *)context;

       这个方法会生成一个数据对象并添加到managedObjectContext里面。

       对于数据的存储,实用managedObjectContext的save方法,上面的代码生成了一个数据对象,加入了context,然后对数据对象进行了初始化,最后储存起来。

       下面再看一段代码,这段代码用于查询所有的数据对象,并返回满足条件的对象数组

    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 *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];    [request setSortDescriptors:sortDescriptors];    [sortDescriptors release];    [sortDescriptor release];        NSError *error = nil;    NSMutableArray *mutableFetchResults = [[self.managedObjectContext executeFetchRequest:request error:&error] mutableCopy];    if (mutableFetchResults) {        self.eventArray = mutableFetchResults;        [mutableFetchResults release];    }    [request release];

        这也是非常常用的一个操作,这里先生成一个fetchRequest,然后告诉request在那个Entity里面查找,设置结束后运行managedObjectContext的executeFetchRequest方法,获得搜索到的所有对象(形成一个数组)

        对数据对象的属性习惯上都是通过KVC来操作的,这里查询实用的是NSSortDescriptor,也可以使用NSPredicate这个类,使用fetchRequest的setPredicate方法设置一下即可。

        对于数据的删除可以使用managedObjectContext的deleteObject方法,最后不要忘记调用save存储。

        简单的数据操作差不多也就这几个内容了,增加,查询,删除,实现起来都很方便。

       

         还有一个提一下,自动生成的数据对象的类(Event等等),里面是没有dealloc方法的,因为Core Data负责数据对象的整个生命周期,也就是说系统会自动的释放数据对象。



原创粉丝点击