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

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

以下看看我写的这个Demo吧

文件结构:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamlqdW55dWFu/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

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

  1. <span style="font-size:14px;">- (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]];
  11.  
  12. //在CoreData为UITableView提供数据的时候。使用NSFetchedReslutsController能提高体验,由于用NSFetchedReslutsController去读数据的话,能最大效率的读取数据库,也方便数据变化后更新界面。
  13. //当我们设置好这个fetch的缓冲值的时候,我们就完毕了创建 NSFetchedRequestController 而且将它传递给了fetch请求,可是这种方法事实上还有下面几个參数:
  14. // 对于managed object 内容,我们值传递内容。
  15.  
  16. //sectionnamekeypath同意我们依照某种属性来分组排列数据内容。
  17. //文件名称的缓存名字应该被用来处理不论什么反复的任务,比方说设置分组或者排列数据等。
  18. NSFetchedResultsController * resultController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:[CoreDataManage GetManagedObjectContext] sectionNameKeyPath:nil cacheName:nil];
  19. resultController.delegate = self;
  20. self.fetchController = resultController;
  21. NSError * error = nil;
  22.  
  23. //操作我们的 fetchedResultsController 而且运行performFetch 方法来取得缓冲的第一批数据。
  24. if ([self.fetchController performFetch:&error])
  25. {
  26. NSLog(@"success");
  27. // NSLog(@"=======%@",[self.fetchController])
  28. }
  29. else
  30. {
  31. NSLog(@"error = %@",error);
  32. }
  33. }
  34. </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] withRowAnimation:UITableViewRowAnimationFade];
  7. break;
  8. case NSFetchedResultsChangeDelete:
  9. [self.contentTableView deleteRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath, nil] withRowAnimation:UITableViewRowAnimationFade];
  10. break;
  11. case NSFetchedResultsChangeMove:
  12. {
  13. [self.contentTableView deleteRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath, nil] withRowAnimation:UITableViewRowAnimationFade];
  14. [self.contentTableView insertRowsAtIndexPaths:[NSArray arrayWithObjects:newIndexPath, 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>

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

  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, BOOL *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. -(IBAction)delete:(id)sender
  24. {
  25. NSArray * arr = [self searchResult];
  26. __block Student * deletemp ;
  27. [arr enumerateObjectsUsingBlock:^(Student * obj, NSUInteger idx, BOOL *stop) {
  28. if ([obj.studentnumber intValue] == 2)
  29. {
  30. deletemp = obj;
  31. *stop = YES;
  32. }
  33. }];
  34. if (deletemp)
  35. {
  36. [[CoreDataManage GetManagedObjectContext] deleteObject:deletemp];
  37. NSLog(@"====ok===delete");
  38. }
  39. }</span><span style="font-size:18px;">
  40. </span>

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

  1. SELECT 0, t0.Z_PK FROM ZFAILEDBANKINFO t0 LEFT OUTER JOIN
  2. ZFAILEDBANKDETAILS t1 ON t0.ZDETAILS = t1.Z_PK
  3. ORDER BY t1.ZCLOSEDATE DESC
  4. total fetch execution time: 0.0033s for 234 rows.
  5.  
  6. SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZNAME, t0.ZSTATE, t0.ZCITY,
  7. t0.ZDETAILS FROM ZFAILEDBANKINFO t0 LEFT OUTER JOIN
  8. ZFAILEDBANKDETAILS t1 ON t0.ZDETAILS = t1.Z_PK WHERE
  9. t0.Z_PK IN (?,?,?
  10.  
  11. ,?,?,?,?,?
  12.  
  13. ,?
  14.  
  15. ,?
  16.  
  17. ,?,?,?
  18.  
  19. ,?
  20.  
  21. ,?
  22.  
  23. ,?,?,?,?,?)
  24. ORDER BY t1.ZCLOSEDATE DESC LIMIT 20
  25. total fetch execution time: 0.0022s for 20 rows.
  26.  
  27. SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZNAME, t0.ZSTATE, t0.ZCITY,
  28. t0.ZDETAILS FROM ZFAILEDBANKINFO t0 LEFT OUTER JOIN
  29. ZFAILEDBANKDETAILS t1 ON t0.ZDETAILS = t1.Z_PK WHERE
  30. t0.Z_PK IN (?,?
  31.  
  32. ,?
  33.  
  34. ,?,?,?,?
  35.  
  36. ,?,?,?,?,?
  37.  
  38. ,?
  39.  
  40. ,?
  41.  
  42. ,?,?,?,?
  43.  
  44. ,?,?)
  45. ORDER BY t1.ZCLOSEDATE DESC LIMIT 20
  46. total fetch execution time: 0.0017s for 20 rows.

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

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

源代码下载

CoreData使用方法二:NSFetchedResultsController实例操作与解说的更多相关文章

  1. 登录操作(方法二:for与else搭配)

    登录操作(方法二:for与else搭配) user_name="star"passwoed='123' count=0for i in range(3): u_username=i ...

  2. 免费开源的DotNet二维码操作组件ThoughtWorks.QRCode(.NET组件介绍之四)

    在生活中有一种东西几乎已经快要成为我们的另一个电子”身份证“,那就是二维码.无论是在软件开发的过程中,还是在普通用户的日常中,几乎都离不开二维码.二维码 (dimensional barcode) , ...

  3. Android抓包方法(二)之Tcpdump命令+Wireshark

    Android抓包方法(二) 之Tcpdump命令+Wireshark 前言 做前端测试,基本要求会抓包,会分析请求数据包,查看接口是否调用正确,数据返回是否正确,问题产生是定位根本原因等.学会抓包分 ...

  4. DotNet二维码操作组件ThoughtWorks.QRCode

    DotNet二维码操作组件ThoughtWorks.QRCode 在生活中有一种东西几乎已经快要成为我们的另一个电子"身份证",那就是二维码.无论是在软件开发的过程中,还是在普通用 ...

  5. python运维开发(二十)----models操作、中间件、缓存、信号、分页

    内容目录 select Form标签数据库操作 models操作F/Q models多对多表操作 Django中间件 缓存 信号 分页 select Form标签补充 在上一节中我们可以知道Form标 ...

  6. ExtJS学习--------Ext.Element中的经常使用事件和其它重要的方法学习(实例)

    经常使用事件: 其它重要方法: 详细实例:(实例结果能够将相应的代码取消凝视进行測试) Ext.onReady(function(){ Ext.create('Ext.panel.Panel',{ t ...

  7. {django模型层(二)多表操作}一 创建模型 二 添加表记录 三 基于对象的跨表查询 四 基于双下划线的跨表查询 五 聚合查询、分组查询、F查询和Q查询

    Django基础五之django模型层(二)多表操作 本节目录 一 创建模型 二 添加表记录 三 基于对象的跨表查询 四 基于双下划线的跨表查询 五 聚合查询.分组查询.F查询和Q查询 六 xxx 七 ...

  8. Vue源码分析(二) : Vue实例挂载

    Vue源码分析(二) : Vue实例挂载 author: @TiffanysBear 实例挂载主要是 $mount 方法的实现,在 src/platforms/web/entry-runtime-wi ...

  9. day 70 Django基础五之django模型层(二)多表操作

    Django基础五之django模型层(二)多表操作   本节目录 一 创建模型 二 添加表记录 三 基于对象的跨表查询 四 基于双下划线的跨表查询 五 聚合查询.分组查询.F查询和Q查询 六 ORM ...

随机推荐

  1. 前端上传文件 后端PHP获取文件

    <body> <form action="03-post-file.php" method="post" enctype="mult ...

  2. ACM 中JAVA的应用

    原文地址:http://www.cppblog.com/vontroy/archive/2010/05/24/116233.html 先说一下Java对于ACM的一些优点吧: (1) 对于熟悉C/C+ ...

  3. Python 之Numpy应用

    NumPy 数据类型 numpy 支持的数据类型比 Python 内置的类型要多很多,基本上可以和 C 语言的数据类型对应上,其中部分类型对应为 Python 内置的类型.下表列举了常用 NumPy ...

  4. CISP/CISA 每日一题 20

    CISSP 每日一题(答) What methods can be used to protectmobile devices such as a smartphone? Encryption,GPS ...

  5. JS/CSS 响应式样式实例

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  6. upf用到的工具

    emulator          : PXP zebu simulator :

  7. Docker---(2)docker pull 下来的镜像存储在哪里

    原文:Docker---(2)docker pull 下来的镜像存储在哪里 版权声明:欢迎转载,请标明出处,如有问题,欢迎指正!谢谢!微信:w1186355422 https://blog.csdn. ...

  8. springboot 使用FreeMarker模板(转)

    在spring boot中使用FreeMarker模板非常简单方便,只需要简单几步就行: 1.引入依赖: <dependency> <groupId>org.springfra ...

  9. 火狐与IE的7个JavaScript差异

    作者注:本篇文章发表于2009.04.27,是一篇关于讨论Javascript在IE6.IE7和FF2+.FF3.0之间的存在的问题的文章. 虽然须要用冗长的JavaScript代码去识别特定的浏览器 ...

  10. 从Unreal Engine 3到Unreal Engine 4

    Unreal Engine 4公布好长好长时间了.直到近期才有时间细致去看一下. TimSweeney老大一句话"IF YOU LOVE SOMETHING, SET IT FREE&quo ...