iOS Core Data的使用

本文介绍了CoreData的概念及其与SQLite的区别,详细解析了NSManagedObject等核心组件的作用,并通过代码示例展示了如何进行数据增删查改操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  初步看了一下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类的代码

  1. @interface Event : NSManagedObject  
  2.   
  3. @property (nonatomic, retain) NSDate * creationDate;  
  4. @property (nonatomic, retain) NSNumber * latitude;  
  5. @property (nonatomic, retain) NSNumber * longitude;  
  6.   
  7. @end  
  1.     <pre name="code" class="html">@implementation Event  
  2.   
  3. @dynamic creationDate;  
  4. @dynamic latitude;  
  5. @dynamic longitude;  
  6.   
  7. @end</pre>  

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

  1. @property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;  
  2. @property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;  
  3. @property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;  
  4.   
  5. - (void)saveContext;  
  6. - (NSURL *)applicationDocumentsDirectory;  

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

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

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

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

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

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

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

  1. NSFetchRequest *request = [[NSFetchRequest alloc] init];  
  2. NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:self.managedObjectContext];  
  3. [request setEntity:entity];  
  4.   
  5. NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"creationDate" ascending:NO];  
  6. NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];  
  7. [request setSortDescriptors:sortDescriptors];  
  8. [sortDescriptors release];  
  9. [sortDescriptor release];  
  10.   
  11. NSError *error = nil;  
  12. NSMutableArray *mutableFetchResults = [[self.managedObjectContext executeFetchRequest:request error:&error] mutableCopy];  
  13. if (mutableFetchResults) {  
  14.     self.eventArray = mutableFetchResults;  
  15.     [mutableFetchResults release];  
  16. }  
  17. [request release];  

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

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

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

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

       

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值