• NSFetchedResultsController实例操作与讲解


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

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

          下面看看我写的这个Demo吧

    文件结构:

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

    1. - (void)viewDidLoad  
    2. {  
    3.     [super viewDidLoad];  
    4.       
    5.     NSFetchRequest * request = [[NSFetchRequest alloc] init];  
    6.     NSEntityDescription * desption = [NSEntityDescription entityForName:TABLE_NAME inManagedObjectContext:[CoreDataManage GetManagedObjectContext]];  
    7.     [request setEntity:desption];  
    8.   
    9.     NSSortDescriptor * desciptor = [NSSortDescriptor sortDescriptorWithKey:@"age" ascending:YES];  
    10.     [request setSortDescriptors:[NSArray arrayWithObjects:desciptor, nil nil]];  
    11.       
    12.     //在CoreData为UITableView提供数据的时候,使用NSFetchedReslutsController能提高体验,因为用NSFetchedReslutsController去读数据的话,能最大效率的读取数据库,也方便数据变化后更新界面,  
    13.     //当我们设置好这个fetch的缓冲值的时候,我们就完成了创建 NSFetchedRequestController 并且将它传递给了fetch请求,但是这个方法其实还有以下几个参数:  
    14.    // 对于managed object 内容,我们值传递内容。  
    15.     //sectionnamekeypath允许我们按照某种属性来分组排列数据内容。  
    16.     //文件名的缓存名字应该被用来处理任何重复的任务,比如说设置分组或者排列数据等。  
    17.     NSFetchedResultsController * resultController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:[CoreDataManage GetManagedObjectContext] sectionNameKeyPath:nil cacheName:nil];  
    18.     resultController.delegate = self;  
    19.     self.fetchController = resultController;  
    20.     NSError * error = nil;  
    21.       
    22.     //操作我们的 fetchedResultsController 并且执行performFetch 方法来取得缓冲的第一批数据。  
    23.     if ([self.fetchController performFetch:&error])  
    24.     {  
    25.         NSLog(@"success");  
    26.        // NSLog(@"=======%@",[self.fetchController])  
    27.     }  
    28.     else  
    29.     {  
    30.         NSLog(@"error = %@",error);  
    31.     }  
    32. }  
    33. </span>  


    配置UITableView

     
    1. - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath  
    2. {  
    3.     return 70;  
    4. }  
    5. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section  
    6. {  
    7.     //section配置  
    8.    // return [[self.fetchController sections] count];  
    9.       
    10.     //row配置  
    11.     if ([[self.fetchController sections] count] > 0) {  
    12.         id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchController sections] objectAtIndex:section];  
    13.         return [sectionInfo numberOfObjects];  
    14.     }  
    15.     else  
    16.     {  
    17.         return 0;  
    18.     }  
    19. }  
    20.   
    21. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath  
    22. {  
    23.     static NSString * mark = @"markIdentifer";  
    24.     ContentCell * cell = [tableView dequeueReusableCellWithIdentifier:mark];  
    25.     if (cell == nil)  
    26.     {  
    27.         cell = [[ContentCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:mark];  
    28.     }  
    29.       
    30.     Student * stu = (Student *)[self.fetchController objectAtIndexPath:indexPath];  
    31.     [cell showModel:stu];  
    32.     return cell;  
    33. }  



    配置NSFetchedResultsController的delegate

     
    1. <span style="font-size:14px;">//当数据发生变化时,点对点的更新tableview,这样大大的提高了更新效率  
    2. - (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath  
    3. {  
    4.     switch (type) {  
    5.         case NSFetchedResultsChangeInsert:  
    6.             [self.contentTableView insertRowsAtIndexPaths:[NSArray arrayWithObjects:newIndexPath, nil nil] withRowAnimation:UITableViewRowAnimationFade];  
    7.             break;  
    8.         case NSFetchedResultsChangeDelete:  
    9.             [self.contentTableView deleteRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath, nil nil] withRowAnimation:UITableViewRowAnimationFade];  
    10.             break;  
    11.         case NSFetchedResultsChangeMove:  
    12.         {  
    13.             [self.contentTableView deleteRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath, nil nil] withRowAnimation:UITableViewRowAnimationFade];  
    14.             [self.contentTableView insertRowsAtIndexPaths:[NSArray arrayWithObjects:newIndexPath, nil nil] withRowAnimation:UITableViewRowAnimationFade];  
    15.         }  
    16.             break;  
    17.         case NSFetchedResultsChangeUpdate:  
    18.         {  
    19.             ContentCell * cell1 = (ContentCell *)[self.contentTableView cellForRowAtIndexPath:indexPath];  
    20.             Student * stu = (Student *)[controller objectAtIndexPath:indexPath];  
    21.             [cell1 showModel:stu];  
    22.         }  
    23.             break;  
    24.               
    25.         default:  
    26.             break;  
    27.     }  
    28. }  
    29.   
    30. //点对点的更新section  
    31. - (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type  
    32. {  
    33.     switch(type) {  
    34.               
    35.         case NSFetchedResultsChangeInsert:  
    36.             [self.contentTableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];  
    37.             break;  
    38.               
    39.         case NSFetchedResultsChangeDelete:  
    40.             [self.contentTableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];  
    41.             break;  
    42.     }  
    43. }  
    44.   
    45. //此方法执行时,说明数据已经发生了变化,通知tableview开始更新UI  
    46. - (void)controllerWillChangeContent:(NSFetchedResultsController *)controller  
    47. {  
    48.     [self.contentTableView beginUpdates];  
    49. }  
    50.   
    51. //结束更新  
    52. - (void)controllerDidChangeContent:(NSFetchedResultsController *)controller  
    53. {  
    54.     [self.contentTableView endUpdates];  
    55. }</span><span style="font-size:18px;">  
    56. </span>  


    添加一个删除按钮的操作,查看效果

     
    1. <span style="font-size:14px;">-(NSArray *)searchResult  
    2. {  
    3.     NSFetchRequest * request = [[NSFetchRequest alloc] init];  
    4.     NSEntityDescription * desption = [NSEntityDescription entityForName:TABLE_NAME inManagedObjectContext:[CoreDataManage GetManagedObjectContext]];  
    5.     [request setEntity:desption];  
    6.       
    7.     NSError * error = nil;  
    8.     NSArray * result = [[CoreDataManage GetManagedObjectContext] executeFetchRequest:request error:&error];  
    9.     if (!error)  
    10.     {  
    11.         [result enumerateObjectsUsingBlock:^(Student * obj, NSUInteger idx, BOOLBOOL *stop) {  
    12.             NSLog(@"--%d,%@,%@,%@,%@--/n",idx,obj.studentnumber,obj.name,obj.age,obj.gender);  
    13.         }];  
    14.           
    15.     }  
    16.     else  
    17.     {  
    18.         NSLog(@"error seach  = %@",error);  
    19.     }  
    20.     return result;  
    21. }  
    22.   
    23.   
    24. -(IBAction)delete:(id)sender  
    25. {  
    26.     NSArray * arr = [self searchResult];  
    27.     __block Student * deletemp ;  
    28.     [arr enumerateObjectsUsingBlock:^(Student * obj, NSUInteger idx, BOOLBOOL *stop) {  
    29.         if ([obj.studentnumber intValue] == 2)  
    30.         {  
    31.             deletemp = obj;  
    32.             *stop = YES;  
    33.         }  
    34.     }];  
    35.     if (deletemp)  
    36.     {  
    37.         [[CoreDataManage GetManagedObjectContext] deleteObject:deletemp];  
    38.         NSLog(@"====ok===delete");  
    39.     }  
    40. }</span><span style="font-size:18px;">  
    41. </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数据库方便多了。

  • 相关阅读:
    各系统终端快速清屏方式
    mvc使用Chsword.Excel2Object导出和导入数据
    winfrom读写txt文件值(短信猫)
    WebDatagrid中添加打开新tab的超链接列
    WebDatagrid前台后台选中行
    WebDatagrid三种获取值得方法javascript
    WebDataMenu做工具栏程序代码
    WebDatagrid-checkbox行如何用js控制其是否可用
    WebDatagrid-左边的checkbox决定右边的文本是否进入编辑状态
    Cell Editing (WebDataGrid) 单元格编辑
  • 原文地址:https://www.cnblogs.com/luqinbin/p/5692398.html
Copyright © 2020-2023  润新知