Core Data 基本用法

#Core Data 学习总结

基本使用

使用 Core Data 基本功能时,涉及到的类

涉及的类描述
NSManagedObjectModel对象模型
NSPersistentStoreCoordinator存储协调器
NSPersistentStore持久化存储文件
NSManagedObjectContext上下文
NSEntityDescription实体描述
NSManagedObject实体对应的类
NSPredicate谓词,即查询条件
NSFetchRequest查询数据的描述

使用 Core Data 时,增删改查等操作均是通过对象上下文来完成的,而构造一个对象上下文,则需要先构造存储协调器,要构造存储协调器则要先有一个对象模型,而对象模型则是由我们创建设计的 .xcdatamodeld 文件初始化得到的,得到存储协调器后,为其添加持久化存储文件。

这样,一个上下文便创建成功,可使用其进行数据的增删改查,具体步骤如下:

  1. 获取模型文件路径,创建模型对象

    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"Model" withExtension:@"momd"];
    NSManagedObjectModel *managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
    
  2. 根据模型对象,创建持久化存储协调器对象

    NSPersistentStoreCoordinator *persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:managedObjectModel];
    
  3. 为协调器添加持久化存储文件

    NSURL *documentURL = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]
    NSURL *storeURL = [documentURL URLByAppendingPathComponent:@"Model.sqlite"];
    NSPersistentStore *persistentStore = [persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error];
    if(!persistentStore){
    	NSLog(@"error!");
    	abort();
    }
    
  4. 创建上下文,并设置协调器

    NSManagedObjectContext *managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
    [managedObjectContext setPersistentStoreCoordinator: persistentStoreCoordinator];
    
  5. 使用上下文插入数据

    Student *stu = [NSEntityDescription insertNewObjectForEntityForName:@"Student" inManagedObjectContext:managedObjectContext];
    stu.name = @"小明";
    stu.age = @(10);
    stu.sex = true;
    stu.grade = @(2);
    stu.classNumber = @(3);
    NSError *error = nil;
    [managedObjectContext save:&error];
    if(error){
    	NSLog(@"插入数据失败");
    }
    
  6. 使用上下文查询数据

    NSFetchRequest *request = [[NSFetchRequest alloc]init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Student" inManagedObjectContext:managedObjectContext];
    [request setEntity:entity];
    // 设定查询条件
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name = '小明'"];
    [request setPredicate:predicate];	
    NSError *error = nil;
    NSArray *result = [managedObjectContext executeFetchRequest:request error:&error];
    if(error){
    	NSLog(@"查询数据失败");
    }
    
  7. 使用上下文删除数据

    for(Student *stu in result) {
        [managedObjectContext deleteObject:stu];
    }
    NSError *error = nil;
    [managedObjectContext save:&error];
    if(error){
    	NSLog(@"删除数据失败");
    }
    

增删改查数据,主要是查询,因为修改或者删除,均要先将数据查询出来,主要使用了类 NSPredicate、NSEntityDescription、NSFetchRequest

数据与视图相关联

Cocoa Touch 中提供了将 Core Data 中的数据与视图相关联的方法,使用 NSFetchedResultsController 类与代理 NSFetchedResultsControllerDelegate 可以方便的将数据与 UITableView 视图相关联,相关代码如下:

@property (nonatomic, strong) NSFetchedResultsController *fetchedController;
@property (nonatomic, strong) UITableView *tableView;

self.fetchedController = [[NSFetchedResultsController alloc]initWithFetchRequest:request
                                                            managedObjectContext: managedObjectContext
                                                              sectionNameKeyPath:nil 
                                                                       cacheName:nil];
[self.fetchedController performFetch:nil];
self.fetchedController.delegate = self;

#pragma mark - UITableViewDelegate,UITableViewDataSource
	
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{    
	return [self.fetchedController.sections[0]numberOfObjects];
}
	
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{
	static NSString *cellID = @"cell";
	Student *stu = [self.fetchedController objectAtIndexPath:indexPath];
	UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
	if (cell == nil){
		cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];
	}
	cell.textLabel.text = stu.name;
	return cell;
}
	
#pragma mark - NSFetchedResultsControllerDelegate
- (void)controller:(NSFetchedResultsController *)controller
   didChangeObject:(id)anObject
       atIndexPath:(NSIndexPath *)indexPath
     forChangeType:(NSFetchedResultsChangeType)type
      newIndexPath:(NSIndexPath *)newIndexPath
{
	switch(type) {
		case NSFetchedResultsChangeInsert:
		    [[self tableView] insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
		    break;
		case NSFetchedResultsChangeDelete:
		    [[self tableView] deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
		    break;
		case NSFetchedResultsChangeUpdate:
		    
		    break;
		case NSFetchedResultsChangeMove:
		    [[self tableView] deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
		    [[self tableView] insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
		    break;
	}
}    

测试代码

数据冲突处理

当 Core Data 从存储文件中获取数据室,会生成一份快照,保存数据的状态,经过修改进而保存时,其会先对比快照与本地文件中的数据,如果一致,则说明数据没有被修改过,然后再进行保存,同时快照也相应更新,如若不一致,说明存储文件中的数据被改动了,那么就需要处理冲突了。

设置 NSManagedObjectContext 的 mergePolicy 属性可以选择不同的处理方式。

@property (strong) id mergePolicy; // default: NSErrorMergePolicy

数据冲突处理策略描述
NSErrorMergePolicy返回错误(默认值)
NSMergeByPropertyStoreTrumpMergePolicy合并修改的部分,冲突的部分使用存储文件中的值
NSMergeByPropertyObjectTrumpMergePolicy合并修改的部分,冲突的部分使用内存中类的属性值
NSOverwriteMergePolicy使用内存中的值,覆盖文件中的所有值
NSRollbackMergePolicy舍弃内存中的值,使用存储文件中的值

另外,我们可以注册通知 NSManagedObjectContextObjectsDidChangeNotification 、NSManagedObjectContextWillSaveNotification 、NSManagedObjectContextDidSaveNotification 监听数据的变动,当2个或多个上下文对象使用同一个存储文件协调器对象时,则其中一个上下文改变了数据,我们可以使用通知,来决定其他的上下文需要做出怎样的反应。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值