CoreData使用方法二:NSFetchedResultsController实例操作与解说
学习了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实例操作与解说的更多相关文章
- 登录操作(方法二:for与else搭配)
登录操作(方法二:for与else搭配) user_name="star"passwoed='123' count=0for i in range(3): u_username=i ...
- 免费开源的DotNet二维码操作组件ThoughtWorks.QRCode(.NET组件介绍之四)
在生活中有一种东西几乎已经快要成为我们的另一个电子”身份证“,那就是二维码.无论是在软件开发的过程中,还是在普通用户的日常中,几乎都离不开二维码.二维码 (dimensional barcode) , ...
- Android抓包方法(二)之Tcpdump命令+Wireshark
Android抓包方法(二) 之Tcpdump命令+Wireshark 前言 做前端测试,基本要求会抓包,会分析请求数据包,查看接口是否调用正确,数据返回是否正确,问题产生是定位根本原因等.学会抓包分 ...
- DotNet二维码操作组件ThoughtWorks.QRCode
DotNet二维码操作组件ThoughtWorks.QRCode 在生活中有一种东西几乎已经快要成为我们的另一个电子"身份证",那就是二维码.无论是在软件开发的过程中,还是在普通用 ...
- python运维开发(二十)----models操作、中间件、缓存、信号、分页
内容目录 select Form标签数据库操作 models操作F/Q models多对多表操作 Django中间件 缓存 信号 分页 select Form标签补充 在上一节中我们可以知道Form标 ...
- ExtJS学习--------Ext.Element中的经常使用事件和其它重要的方法学习(实例)
经常使用事件: 其它重要方法: 详细实例:(实例结果能够将相应的代码取消凝视进行測试) Ext.onReady(function(){ Ext.create('Ext.panel.Panel',{ t ...
- {django模型层(二)多表操作}一 创建模型 二 添加表记录 三 基于对象的跨表查询 四 基于双下划线的跨表查询 五 聚合查询、分组查询、F查询和Q查询
Django基础五之django模型层(二)多表操作 本节目录 一 创建模型 二 添加表记录 三 基于对象的跨表查询 四 基于双下划线的跨表查询 五 聚合查询.分组查询.F查询和Q查询 六 xxx 七 ...
- Vue源码分析(二) : Vue实例挂载
Vue源码分析(二) : Vue实例挂载 author: @TiffanysBear 实例挂载主要是 $mount 方法的实现,在 src/platforms/web/entry-runtime-wi ...
- day 70 Django基础五之django模型层(二)多表操作
Django基础五之django模型层(二)多表操作 本节目录 一 创建模型 二 添加表记录 三 基于对象的跨表查询 四 基于双下划线的跨表查询 五 聚合查询.分组查询.F查询和Q查询 六 ORM ...
随机推荐
- VB 宏+mysql解决EXCEL表格实现自动化处理
1.表格模板自动建立源码 Sub opp()Dim myPath$, myFile$, AK As WorkbookApplication.ScreenUpdating = FalsemyPath = ...
- Docker+SVN
原文:Docker+SVN mkdir /cnex/svndocker pull garethflowers/svn-server docker run -d --name svn-server - ...
- 三、Docker镜像的相关操作
原文:三.Docker镜像的相关操作 一.查看本地镜像: docker images 二.使用某个镜像来运行容器: docker run -t -i xxxx(镜像名):xx.xx(版本,不带即最新) ...
- 24. Spring Boot 事务的使用
转自:https://blog.csdn.net/catoop/article/details/50595702
- Qt产生随机数(两种方法)
第一种方法 #include <QTime> QTime time; time= QTime::currentTime(); qsrand(time.msec()+time.second( ...
- 页面事件(Init,Load,PreRender)执行顺序
简介 对由 Microsoft® Internet 信息服务 (IIS) 处理的 Microsoft® ASP.NET 页面的每个请求都会被移交到 ASP.NET HTTP 管道.HTTP 管道由一系 ...
- Javascript和jquery事件--事件监听器
之前看完了js和jq的冒泡捕获和事件对象event,这里看看同时使用js和jq后我最容易混淆的监听器的绑定. (1) js的监听器绑定解绑 绑定监听器有两种方式: a.on-事件type,比如oncl ...
- Javascript和jquery事件--事件对象event
1. 事件对象event 对于event,js的解释是Event 对象代表事件的状态,比如事件在其中发生的元素.键盘按键的状态.鼠标的位置.鼠标按钮的状态.而jq的解释是事件处理(事件对象.目标元素 ...
- bootstrap课程5 bootstrap中的组件使用的注意事项是什么
bootstrap课程5 bootstrap中的组件使用的注意事项是什么 一.总结 一句话总结: 1.img-responsive的作用是什么(其实还是要多看手册)? 看起来像width=100%的效 ...
- linux 内核源代码目录结构
/arch:目录包括了所有和体系结构相关的核心代码.它下面的每一个子目录都代表一种Linux支持的体系结构,例如i386就是Intel CPU及与之相兼容体系结构的子目录.PC机一般都基于此目录. / ...