学习了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="">

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

<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实例操作与解说的更多相关文章

  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. DG查看恢复进度

    查看恢复进度 (1)查看进程的活动状态 V$MANAGED_STANDBY视图专用于显示物理Standby数据库相关进程的当前状态,该视图中的列也很有特点,查看进程状态时,通常我们会关注PROCESS ...

  2. linux网络防火墙-iptables基础详解

    一:前言 防火墙,其实说白了讲,就是用于实现Linux下访问控制的功能的,它分为硬件的或者软件的防火墙两种.无论是在哪个网络中,防火墙工作的地方一定是在网络的边缘.而我们的任务就是需要去定义到底防火墙 ...

  3. Docker+Mongodb

    原文:Docker+Mongodb docker search mongodb docker run -d -p 2701:27017 -v /usr/mongodb/data:/data/db  - ...

  4. 业余学习react 学习记录

    http://www.ruanyifeng.com/blog/2015/03/react (阮一峰 react 学习) 1.搭建环境:npm 使用 React npm install -g cnpm ...

  5. Excel查询序列所相应的值-vLoopup函数,求比例分子改变但分母不变

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveWV3ZWlvdXlhbmc=/font/5a6L5L2T/fontsize/400/fill/I0JBQk ...

  6. 利用安卓手机的OTG共享有线网络

    利用安卓手机的OTG共享有线网络 安卓手机有些是支持OTG的,OTG的显著特点就是手机能给外部设备供电,而且能交换数据. 那么,没有OTG功能的手机能不能给弄个OTG出来呢?当然可以,原因很简单,既然 ...

  7. HTML基础第五讲---控制表格及其表项的对齐方式

    转自:https://i.cnblogs.com/posts?categoryid=1121494 缺省情况下,表格在浏览器屏幕上左对齐,你可以使用<TABLE>的ALIGN属性来指定表格 ...

  8. 14.inline与namespace使用

    #include <iostream> using namespace std; namespace all { //inline作用为默认调用 inline namespace V201 ...

  9. h.264硬件解码

    // H264HWDecoder.m // H264EncoderDecoder // // Created by lujunjie on 2016/11/28. // Copyright © 201 ...

  10. 怎样用Adobe Acrobat 7 Pro把PDF文档拆分成多个啊?

    这个pdf文档里有多篇文章,我想把他们分开并分别保存在独立的pdf文档.怎么操作?我的电脑基础不太好,麻烦说得详细一些. Adobe Acrobat 7 Pro拆分PDF文档的方法: 1.点左边的“书 ...