zoukankan      html  css  js  c++  java
  • CoreData使用方法二:NSFetchedResultsController实例操作与解说

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

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

          以下看看我写的这个Demo吧

    文件结构:



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

    <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数据库方便多了。


    源代码下载





  • 相关阅读:
    python运行错误---TabError: Inconsistent use of tabs and spaces in indentation
    python运行错误------Non-UTF-8 code
    opencv错误(Unhandled expection at at 0x0007EEE...)
    fatal error LNK1112: 模块计算机类型“X86”与目标计算机类型“x64”冲突——我的解决方案
    基础术语
    opencv
    图像归一化
    人脸相关数据库
    堆排序
    abp学习(二)
  • 原文地址:https://www.cnblogs.com/zhchoutai/p/7395833.html
Copyright © 2011-2022 走看看