CoreData使用方法二:NSFetchedResultsController实例操作与解说

摘要:
以NSFeededResultsController为例。它与UITableView一起使用。它可以最大化UITableView的UI更新效率。例如,如果我们删除了一个项目,我们只需要运行以删除数据库中的一条信息。然后,通过配置NSFeededResultsController的委托方法,它将自动查找我们删除的信息。使用NSFeededReslutsController可以改善体验。因为使用NSFeededReslutsController读取数据可以最大限度地提高读取数据库的效率,也有助于在数据更改后更新接口。

        学习了NSFetchedResultsController。才深深的体会到coredata的牛逼之处。原来Apple公司弄个新技术。不是平白无故的去弄,会给代码执行到来非常大的优点。coredata不仅能让我们大大的降低代码量。还最大化的提高执行效率。

       就拿NSFetchedResultsController来说吧,他是和UITableView搭配使用的。能够最大化的提高UITableView的UI更新效率,比方我们删除一个东西,仅仅须要运行删除数据库里面的一条信息,然后通过配置NSFetchedResultsController的delegate方法,它自己主动会找到我们删除的那条信息。然后自己主动更新UI。最重要的时它不是总体的去更新UITableView,他是仅仅操作了须要删除的哪一个。这就是他的伟大之处。

      以下看看我写的这个Demo吧

文件结构:

CoreData使用方法二:NSFetchedResultsController实例操作与解说第1张


将数据库中得数据放到缓冲区中:

<span style="font-size:14px;">- (void)viewDidLoad
{
    [super viewDidLoad];
    
    NSFetchRequest * request = [[NSFetchRequest alloc] init];
    NSEntityDescription * desption = [NSEntityDescription entityForName:TABLE_NAME inManagedObjectContext:[CoreDataManage GetManagedObjectContext]];
    [request setEntity:desption];

    NSSortDescriptor * desciptor = [NSSortDescriptor sortDescriptorWithKey:@"age" ascending:YES];
    [request setSortDescriptors:[NSArray arrayWithObjects:desciptor, nil]];
    
    //在CoreData为UITableView提供数据的时候。使用NSFetchedReslutsController能提高体验,由于用NSFetchedReslutsController去读数据的话,能最大效率的读取数据库,也方便数据变化后更新界面。
    //当我们设置好这个fetch的缓冲值的时候,我们就完毕了创建 NSFetchedRequestController 而且将它传递给了fetch请求,可是这种方法事实上还有下面几个參数:
   // 对于managed object 内容,我们值传递内容。

//sectionnamekeypath同意我们依照某种属性来分组排列数据内容。 //文件名称的缓存名字应该被用来处理不论什么反复的任务,比方说设置分组或者排列数据等。 NSFetchedResultsController * resultController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:[CoreDataManage GetManagedObjectContext] sectionNameKeyPath:nil cacheName:nil]; resultController.delegate = self; self.fetchController = resultController; NSError * error = nil; //操作我们的 fetchedResultsController 而且运行performFetch 方法来取得缓冲的第一批数据。 if ([self.fetchController performFetch:&error]) { NSLog(@"success"); // NSLog(@"=======%@",[self.fetchController]) } else { NSLog(@"error = %@",error); } } </span>


配置UITableView

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 70;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    //section配置
   // return [[self.fetchController sections] count];
    
    //row配置
    if ([[self.fetchController sections] count] > 0) {
        id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchController sections] objectAtIndex:section];
        return [sectionInfo numberOfObjects];
    }
    else
    {
        return 0;
    }
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString * mark = @"markIdentifer";
    ContentCell * cell = [tableView dequeueReusableCellWithIdentifier:mark];
    if (cell == nil)
    {
        cell = [[ContentCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:mark];
    }
    
    Student * stu = (Student *)[self.fetchController objectAtIndexPath:indexPath];
    [cell showModel:stu];
    return cell;
}


配置NSFetchedResultsController的delegate

<span style="font-size:14px;">//当数据发生变化时,点对点的更新tableview,这样大大的提高了更新效率
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath
{
    switch (type) {
        case NSFetchedResultsChangeInsert:
            [self.contentTableView insertRowsAtIndexPaths:[NSArray arrayWithObjects:newIndexPath, nil] withRowAnimation:UITableViewRowAnimationFade];
            break;
        case NSFetchedResultsChangeDelete:
            [self.contentTableView deleteRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath, nil] withRowAnimation:UITableViewRowAnimationFade];
            break;
        case NSFetchedResultsChangeMove:
        {
            [self.contentTableView deleteRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath, nil] withRowAnimation:UITableViewRowAnimationFade];
            [self.contentTableView insertRowsAtIndexPaths:[NSArray arrayWithObjects:newIndexPath, nil] withRowAnimation:UITableViewRowAnimationFade];
        }
            break;
        case NSFetchedResultsChangeUpdate:
        {
            ContentCell * cell1 = (ContentCell *)[self.contentTableView cellForRowAtIndexPath:indexPath];
            Student * stu = (Student *)[controller objectAtIndexPath:indexPath];
            [cell1 showModel:stu];
        }
            break;
            
        default:
            break;
    }
}

//点对点的更新section
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
{
    switch(type) {
            
        case NSFetchedResultsChangeInsert:
            [self.contentTableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;
            
        case NSFetchedResultsChangeDelete:
            [self.contentTableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}

//此方法运行时,说明数据已经发生了变化。通知tableview開始更新UI
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
    [self.contentTableView beginUpdates];
}

//结束更新
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
    [self.contentTableView endUpdates];
}</span><span style="font-size:18px;">
</span>

加入一个删除button的操作。查看效果

<span style="font-size:14px;">-(NSArray *)searchResult
{
    NSFetchRequest * request = [[NSFetchRequest alloc] init];
    NSEntityDescription * desption = [NSEntityDescription entityForName:TABLE_NAME inManagedObjectContext:[CoreDataManage GetManagedObjectContext]];
    [request setEntity:desption];
    
    NSError * error = nil;
    NSArray * result = [[CoreDataManage GetManagedObjectContext] executeFetchRequest:request error:&error];
    if (!error)
    {
        [result enumerateObjectsUsingBlock:^(Student * obj, NSUInteger idx, BOOL *stop) {
            NSLog(@"--%d,%@,%@,%@,%@--/n",idx,obj.studentnumber,obj.name,obj.age,obj.gender);
        }];
        
    }
    else
    {
        NSLog(@"error seach  = %@",error);
    }
    return result;
}


-(IBAction)delete:(id)sender
{
    NSArray * arr = [self searchResult];
    __block Student * deletemp ;
    [arr enumerateObjectsUsingBlock:^(Student * obj, NSUInteger idx, BOOL *stop) {
        if ([obj.studentnumber intValue] == 2)
        {
            deletemp = obj;
            *stop = YES;
        }
    }];
    if (deletemp)
    {
        [[CoreDataManage GetManagedObjectContext] deleteObject:deletemp];
        NSLog(@"====ok===delete");
    }
}</span><span style="font-size:18px;">
</span>

如今编译执行你的应用的话。表面上看起来应该都是一样的,可是假设你看看控制台的话,惊人的事情正在发生:

SELECT 0, t0.Z_PK FROM ZFAILEDBANKINFO t0 LEFT OUTER JOIN
    ZFAILEDBANKDETAILS t1 ON t0.ZDETAILS = t1.Z_PK
    ORDER BY t1.ZCLOSEDATE DESC
total fetch execution time: 0.0033s for 234 rows.

SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZNAME, t0.ZSTATE, t0.ZCITY,
    t0.ZDETAILS FROM ZFAILEDBANKINFO t0 LEFT OUTER JOIN
    ZFAILEDBANKDETAILS t1 ON t0.ZDETAILS = t1.Z_PK WHERE
    t0.Z_PK IN  (?,?,?

,?,?,?,?,?

,?

,?

,?,?,?

,?

,?

,?,?,?,?,?) ORDER BY t1.ZCLOSEDATE DESC LIMIT 20 total fetch execution time: 0.0022s for 20 rows. SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZNAME, t0.ZSTATE, t0.ZCITY, t0.ZDETAILS FROM ZFAILEDBANKINFO t0 LEFT OUTER JOIN ZFAILEDBANKDETAILS t1 ON t0.ZDETAILS = t1.Z_PK WHERE t0.Z_PK IN (?,?

,?

,?,?,?,?

,?,?,?,?,?

,?

,?

,?,?,?,?

,?,?) ORDER BY t1.ZCLOSEDATE DESC LIMIT 20 total fetch execution time: 0.0017s for 20 rows.

你能够看到, NSFetchedResultsController 正在从 FailedBankInfo中依照之前设置的顺序取得大量的ID,依据UITableView的情况每次仅仅缓冲一定数量的数据。

比我们直接操控sqlite数据库方便多了。


源代码下载





免责声明:文章转载自《CoreData使用方法二:NSFetchedResultsController实例操作与解说》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Ansible工作流程详解PLSQL碰到pls-00103的错误解决办法下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

使用 AFNetworking 进行 XML 和 JSON 数据请求

(1)XML 数据请求 使用 AFNetworking 中的 AFHTTPRequestOperation 和 AFXMLParserResponseSerializer,另外结合第三方框架 XMLDictionary 进行数据转换 使用 XMLDictionary 的好处:有效避免自行实现 NSXMLParserDelegate 委托代理协议方法来进行繁...

ios开发UI篇—使用纯代码自定义UItableviewcell实现一个简单的微博界面布局

一、实现效果 二、使用纯代码自定义一个tableview的步骤 1.新建一个继承自UITableViewCell的类 2.重写initWithStyle:reuseIdentifier:方法 添加所有需要显示的子控件(不需要设置子控件的数据和frame, 子控件要添加到contentView中) 进行子控件一次性的属性设置(有些属性只需要设置一次,比如字...

iOS-高仿通讯录之商品索引排序搜索

概述 TableView添加右侧索引, 将数据按照索引分组排序, 并添加搜索功能且在搜索界面复用当前页面. 详细 代码下载:http://www.demodashi.com/demo/10696.html 项目中像一些商品搜索类界面, TableView添加右侧索引的使用越来越多, 的确用户体验提高了许多. 一、主要思路 大致思路: 1....

使用FDTemplateLayout框架打造个性App

效果展示 project下载地址 · 进入构建结构 首先我们新建一个project 接下来我们拖进来一个Table View Controller,将Storyboard Entry Point指向我们的Table View Controller。 原来的ViewController就能够删除了。 效果如图所看到的 选中Table View C...

iOS数据持久化的方式

概论 所谓的持久化,就是将数据保存到硬盘中,使得在应用程序或机器重启后可以继续访问之前保存的数据。在iOS开发中,有很多数据持久化的方案,接下来我将尝试着介绍一下5种方案: plist文件(属性列表) preference(偏好设置) NSKeyedArchiver(归档) SQLite 3 CoreData 沙盒 在介绍各种存储方法之前,有必要说明以...

类似西瓜视频、抖音的自动播放库

AutoVideoPlayer Play/pause videos automatically in UITableview when an UITableViewCell is in focus, videos can be easily embedded in any UITableViewCell subclass. Can be easily ex...