基本概念
在CoreData有一些概念刚学习的时候不是很容易理解,还是要单独拿出来来梳理一下,这样学后面的内容不会感觉吃力。

♥ 表结构:NSEntityDescription
♥ 表记录:NSManagedObject

--------------------------------------------------------------------------------

♥ 数据库存放方式:NSPersistentStoreCoordinator(持久化存储协调者)
♥ 数据库操作:NSManagedObjectContext(被管理的对象上下文)
还有一些类NSManagedObjectModel、NSFetchRequest什么的,具体项目就会有体会,下面来实战一下。

新建一个项目,项目模板基于“Master-Detail Application”,点击“Next”按钮,项目命名为“SimpleCoreData”,并勾选“Use Core Data”,点击“Next”,选择项目保存的目录,点击“Create”按钮,项目创建完毕。

代码分析
比以前创建的简单项目多了不少代码,还有xcdatamodeld文件,慢慢分析代码,AppDelegate.h头文件中,添加了三个property

@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
再分析AppDelegate.m文件,有对应的三个方法来返回各自对应的对象

#pragma mark - Core Data stack
 
- (NSManagedObjectContext *)managedObjectContext
{
...
    return __managedObjectContext;
}
 
- (NSManagedObjectModel *)managedObjectModel
{
... 
    return __managedObjectModel;
}
 
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
...
    return __persistentStoreCoordinator;
}
这些对象在哪里被调用的呢,打开MasterViewController.m,在初始化函数中,我们看到通过获取delegate,再通过delegate调用方法managedObjectContext,这样就得到了这个NSManagedObjectContext对象,NSManagedObjectContext对象它会跟NSPersistentStoreCoordinator对象打交道,NSPersistentStoreCoordinator会去处理底层的存储方式。

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        self.title = NSLocalizedString(@"Master", @"Master");
        id delegate = [[UIApplication sharedApplication] delegate];
        self.managedObjectContext = [delegate managedObjectContext];
    }
    return self;
}查询实体
分析MasterViewController.m的代码发现以下函数的调用顺序。

♥ -tableView:(UITableView *)tableView cellForRowAtIndexPath:
♥ -configureCell:atIndexPath:
♥ -fetchedResultsController
最后是从fetchedResultsController获取到查询结果,那就有必要来分析一下

- (NSFetchedResultsController *)fetchedResultsController
{
    // 如果查询结果已经存在就直接返回__fetchedResultsController
    if (__fetchedResultsController != nil)
    {
        return __fetchedResultsController;
    }
 
    // 1.创建NSFetchRequest对象(相当于SQL语句)
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
 
    // 2.创建查询实体(相当于设置查询哪个表)
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entity];
 
    // 设置获取数据的批数.
    [fetchRequest setFetchBatchSize:20];
 
    // 3.创建排序描述符,(ascending:是否升序)
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"timeStamp" ascending:NO];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
 
    [fetchRequest setSortDescriptors:sortDescriptors];
 
    // 根据fetchRequest和managedObjectContext来创建aFetchedResultsController对象,并设置缓存名字为"Master".
    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:@"Master"];
 
    // 设置aFetchedResultsController的委托对象为当前类
    aFetchedResultsController.delegate = self;
    self.fetchedResultsController = aFetchedResultsController;
 
 NSError *error = nil;
    // 获取第一批数据
 if (![self.fetchedResultsController performFetch:&error])
        {
        // 错误处理
     NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
     abort();
 }
 
    return __fetchedResultsController;
}
因为我们设置了aFetchedResultsController的委托NSFetchedResultsControllerDelegate,就要实现它的方法,幸运的是这些方法看起来都像下面这样,直接复制粘贴就行了。

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
    [self.tableView beginUpdates];
}
 
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
           atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
{
    switch(type)
    {
        case NSFetchedResultsChangeInsert:
            [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;
 
        case NSFetchedResultsChangeDelete:
            [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}
 
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
       atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
      newIndexPath:(NSIndexPath *)newIndexPath
{
    UITableView *tableView = self.tableView;
 
    switch(type)
    {
 
        case NSFetchedResultsChangeInsert:
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;
 
        case NSFetchedResultsChangeDelete:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;
 
        case NSFetchedResultsChangeUpdate:
            [self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
            break;
 
        case NSFetchedResultsChangeMove:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}
 
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
    [self.tableView endUpdates];
}添加实体- (void)insertNewObject
{
    // 从NSFetchedResultsController中获取NSManagedObjectContext对象
    NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];
 
    // 从NSFetchedResultsController中获取实体描述
    NSEntityDescription *entity = [[self.fetchedResultsController fetchRequest] entity];
 
    // 在被管理上下文中插入一个新的NSManagedObject
    NSManagedObject *newManagedObject = [NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context];
 
    // 字段赋值
    [newManagedObject setValue:[NSDate date] forKey:@"timeStamp"];
 
    // 保存被管理对象上下文,这样刚才的newManagedObject就被保存了
    NSError *error = nil;
    if (![context save:&error])
    {
        // 错误处理.
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }
}删除实体// 从NSFetchedResultsController中获取NSManagedObjectContext对象
NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];
 
// 从被管理对象上下文中删除MO对象
[context deleteObject:[self.fetchedResultsController objectAtIndexPath:indexPath]];
 
// 保存被管理对象上下文
NSError *error = nil;
if (![context save:&error])
{
    // 错误处理
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    abort();
}
这个删除对象为什么没有处理TableView的代码,因为我们实现NSFetchedResultsControllerDelegate委托,当对象上下文发生变化时NSFetchedResultsControllerDelegate的实现方法会处理这些事情。

CoreData基础相关推荐

  1. coreData数据操作

    // 1. 建立模型文件 // 2. 建立CoreDataStack // 3. 设置AppDelegate 接着 // // CoreDataStack.swift // CoreDataStack ...

  2. 从Windows角度看Mac OS X上的软件开发

    如果原来从事Windows软件开发,想跨足或转换至Mac OS X环境,需要知道那些东西?有什么知识技能可以快速运用在Mac OS X环境上的?这两个问题应该是Windows开发者进入Mac OS X ...

  3. CoreData相关01 基础及运用:添加、查询、过滤、排序、分页

    CoreData CoreData中几乎不用写数据库操作语句就能完成数据的本地化存储. CoreData和iOS中的模型对象相联系在一起,只需要操作模型对象的增删改查就可以完成数据的增删改查,不用写S ...

  4. 使用CoreData的轻量级自动数据迁移

    使用IOS的CoreData进行存储很方便,CoreData已经帮我们做了很多基础的工作,一般情况下没必要自己操作数据库了. 在开发中修改了实体模型,可能会遇到schema incompatibili ...

  5. 让CoreData更简单些

    从简书迁移到掘金 前言 本文并不是CoreData从入门到精通之类的教程, 并不会涉及到过多的原理概念描述, 而是介绍如何让CoreData的使用变得更加简单明了, 方便亲民. 全文约六千字, 预计花 ...

  6. coredata 数据库升级

    在真实开发中,因为需求是不断变化的,说不定什么时候就需要往模型里添加新的字段,添加新的模型,甚至是大规模的重构:所以数据的迁移就显得尤为重要了. CoreData 中,数据迁移本质就是把旧的 SQLi ...

  7. iOS持久化存储-CoreData简介

    本文目录 一.简介 二.模型文件 三.了解NSManagedObject对象 四.CoreData中的核心对象 五.代码实现 六.打开CoreData的SQL语句输出开关 七.创建NSManagedO ...

  8. .net core 基于Dapper 的分库分表开源框架(core-data)

    一.前言 感觉很久没写文章了,最近也比较忙,写的相对比较少,抽空分享基于Dapper 的分库分表开源框架core-data的强大功能,更好的提高开发过程中的效率:在数据库的数据日积月累的积累下,业务数 ...

  9. R-大数据分析挖掘(5-R基础回顾)

    (一)R函数 R是一种解析型语言,输入后可直接获取结果 函数(输入参数,参数) R的函数分为"高级"和"低级函数" • 高级函数可调用低级函数 • 高级函数称为 ...

最新文章

  1. 基建狂魔:硬核技术之隔绝厌氧菌的涂料
  2. 《JAVA练习题目2》 输入十个学生的考试成绩,将及格学生的成绩从高到低排序输出。
  3. C语言放大字符怎么编程,c语言中怎么将个别字体放大,如9,将其放大,怎么编程呢?...
  4. 巴什博弈例题:NYOJ23;HDU:2149,1847,2897,2188
  5. “暧昧”的吉本,“疗伤”的芭娜娜
  6. linux模式匹配,sed的模式匹配用法探讨
  7. java 加法 溢出_StackOverflow热帖:Java整数相加溢出怎么办?Java8一步搞定~
  8. hadoop和spark的区别和联系
  9. js list 合并_VIM学习笔记 脚本-列表(Script-List)
  10. python修改散点图中点的颜色_如何在seaborn散点图中更改点边颜色?
  11. oracle_sqlserver和mysql获取表外键的方法_MYSQL教程如何获取SqlServer2005表结构(字段,主键,外键,递增,描述)...
  12. 【20保研】天津大学智能与计算学部2020级研究生招生夏令营活动通知
  13. 华硕路由 ac ax_【路由器】华硕网络开启802.11ax电竞生态
  14. 数据结构(三)---树
  15. 《数据结构》实验报告五:二叉树
  16. js class super 的用法
  17. 制作Wi-Fi Ducky远程HID攻击设备
  18. 我们不生产代码,我们是代码的搬运工
  19. 2022/10/17-10/22周报
  20. 线性代数Python计算:解可逆系数矩阵线性方程组

热门文章

  1. 模式分解的无损连接性之深入剖析
  2. math函数常用操作
  3. H.266/VVC-VTM代码学习18-自适应QP设置(Adaptive QP)
  4. 利用 conda install --use-local 安装 解决 Tensorflow: illegal instruction (core dumped)
  5. Python—reverse()和reversed()方法介绍
  6. 《HikariCP数据库连接池实战》学习笔记(二):获取连接原理
  7. 渗透常用SQL注入语句大全
  8. Android之手机振动和振铃
  9. 深入Vue底层,手写一个vuex
  10. 代码函数从零开始学习OpenCL开发(二)一个最简单的示例与简单性能分析