获取tableView刷新完成状态
来源:互联网 发布:c语言乘法口诀 编辑:程序博客网 时间:2024/04/24 10:57
最近有个需求,需要获取tableView的刷新完成状态去做一些事情,找了好多方法,最终在http://stackoverflow.com/questions/16071503/how-to-tell-when-uitableview-has-completed-reloaddata这里找到了答案 。
两种方式 一种是
[self.tableView reloadData]; [self.tableView layoutIfNeeded];
// do sth
另外一种是
[self.tableView reloadData];dispatch_async(dispatch_get_main_queue(), ^{ // do sth});
第一种方式是刷新的时候强制tableView 立即刷新,第二种是获取主线程队列,然后当tableView刷新完成之后会调用这个GCD的block。个人比较倾向于第二种方式,于是想探究一下原理。
之前有人说[tableView reloadData}是异步的,其实并不是,下面代码验证了我的说法
我在这里- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString * cellID = @"cell";
TableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:cellID];
if(!cell){
cell = [[TableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];
}
NSLog(@"cell index :%ld",(long)indexPath.row);
[cell cellRelaodData];
return cell;
}
打印每个cell,然后调用- (void)viewDidLoad {
NSLog(@"tableView reloadData start");
[_tableView reloadData];//
sleep(5);
}
[_tableView reloadData]如果说reload是异步的,那么即使主线程阻塞,它也会执行刷新操作,我们来看打印结果:
2015-12-04 10:40:15.524 RunLoop[17929:2244708] tableView reloadData start
2015-12-04 10:40:20.577 RunLoop[17929:2244708] cell index :0
2015-12-04 10:40:20.615 RunLoop[17929:2244708] cell index :1
2015-12-04 10:40:20.616 RunLoop[17929:2244708] cell index :2
tableView是在5秒之后才刷新的,那么它一定是同步的!!
那既然是同步的,他又是什么时候执行的呢?
- (void)viewDidLoad {
NSLog(@"tableView reloadData start");
[_tableView reloadData];//
[self test];
}
test函数里面打印了一句话,我们再来看log
2015-12-04 10:43:24.408 RunLoop[17970:2250279] tableView reloadData start
2015-12-04 10:43:24.409 RunLoop[17970:2250279] the test method is end
2015-12-04 10:43:24.434 RunLoop[17970:2250279] cell index :0
2015-12-04 10:43:24.440 RunLoop[17970:2250279] cell index :1
2015-12-04 10:43:24.441 RunLoop[17970:2250279] cell index :2
是在tableView reloadData操作所在的函数执行完毕之后才执行的。。我们继续改代码
- (void)viewDidLoad {
NSLog(@"tableView reloadData start");
[_tableView reloadData];//
[self test];
dispatch_async(dispatch_get_main_queue(), ^{ //2
NSLog(@"tableView reloadData complete");
});
NSLog(@"the last line of current selector");
}
再看log
2015-12-0410:45:54.588 RunLoop[18009:2255040] tableView reloadData start
2015-12-0410:45:54.589 RunLoop[18009:2255040] the test method is end
2015-12-0410:45:54.589 RunLoop[18009:2255040] the last line of current selector
2015-12-0410:45:54.615 RunLoop[18009:2255040] cell index :0
2015-12-0410:45:54.620 RunLoop[18009:2255040] cell index :1
2015-12-0410:45:54.621 RunLoop[18009:2255040] cell index :2
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
2015-12-0410:45:54.665 RunLoop[18009:2255040] cell index :96
2015-12-0410:45:54.666 RunLoop[18009:2255040] cell index :97
2015-12-0410:45:54.666 RunLoop[18009:2255040] cell index :98
2015-12-0410:45:54.666 RunLoop[18009:2255040] cell index :99
2015-12-0410:45:54.916 RunLoop[18009:2255040] tableView reloadData complete
执行顺序是viewdidLoad->test->table ralodData->
dispatch_async(dispatch_get_main_queue(), ^{}的block。
接下来我们添加一个runloop的observer
- (void)runLoopObsevers{
// 创建RunLoop即将唤醒监听者
CFRunLoopObserverRef observer =CFRunLoopObserverCreateWithHandler(CFAllocatorGetDefault(),kCFRunLoopAllActivities,YES,0, ^(CFRunLoopObserverRef observer,CFRunLoopActivity activity) {
switch (activity) {
casekCFRunLoopEntry:
NSLog(@"即将进入Loop");
break;
casekCFRunLoopBeforeTimers:
NSLog(@"即将处理 Timer");
break;
casekCFRunLoopBeforeSources:
NSLog(@"即将处理 Source");
break;
casekCFRunLoopBeforeWaiting:
NSLog(@"即将进入休眠");
break;
casekCFRunLoopAfterWaiting:
NSLog(@"刚从休眠中唤醒");
break;
case kCFRunLoopExit:
NSLog(@"即将退出Loop");
break;
default:
break;
}
});
// 向当前runloop添加监听者
CFRunLoopAddObserver(CFRunLoopGetMain(), observer,kCFRunLoopDefaultMode);
// 释放内存
CFRelease(observer);
}
[selfrunLoopObsevers];
再来看log2015-12-04 11:10:35.241 RunLoop[1107:54022] cell index :2
2015-12-04 11:10:35.242 RunLoop[1107:54022] cell index :3
2015-12-04 11:10:35.243 RunLoop[1107:54022] cell index :4
2015-12-04 11:10:35.243 RunLoop[1107:54022] cell index :5
2015-12-04 11:10:35.244 RunLoop[1107:54022] cell index :6
2015-12-04 11:10:35.245 RunLoop[1107:54022] cell index :7
2015-12-04 11:10:35.492 RunLoop[1107:54022]即将进入Loop
2015-12-04 11:10:35.493 RunLoop[1107:54022]即将处理 Timer
2015-12-29 11:10:35.493 RunLoop[1107:54022] 即将处理 Source
2015-12-29 11:10:35.494 RunLoop[1107:54022] tableView reloadData complete
2015-12-29 11:10:35.494 RunLoop[1107:54022] 即将处理 Timer
2015-12-29 11:10:35.495 RunLoop[1107:54022] 即将处理 Source
runloop优先处理了tableview reloadData的任务,之后进入休眠,被dispatch_get_main_queue的任务唤醒,它的block只有在当前的主线程空闲的时候才有机会被runloop处理,所以最终这种方式可以获取到tableView的刷新完成状态.
最后献上完整版:
dispatch_async(dispatch_get_main_queue(), ^{
});[self.tableView reloadData]; dispatch_async(dispatch_get_main_queue(), ^{ // do sth });
外层的dispatch_async(dispatch_get_main_queue(), ^{})是为了保证调用reloadData函数的时候其他的工作已经做完了。
runloop的参考资料在这里
http://www.cocoachina.com/ios/20150601/11970.html
https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html#//apple_ref/doc/uid/10000057i-CH16-SW1
以上是个人理解,欢迎大家讨论指正。
- 获取tableView刷新完成状态
- uisearchDisplayController放在tableview里下拉刷新状态出现遮挡
- tableView 头部添加状态 今日头条刷新数据效果
- tableView刷新
- tableview刷新
- 获取Andorid的ListView在完成刷新后的事件
- tableview下拉刷新
- TableView下拉刷新
- tableview下拉刷新
- tableView 刷新单行
- tableView 局部刷新
- tableView的刷新
- tableView - 数据刷新
- tableView的刷新
- tableview-数据刷新
- tableView刷新某一行
- tableView的刷新
- tableView的刷新
- view编程概览---介绍
- C++ Template 中的typename、class关键字
- Valid Sudoku 数独的有效性
- ExtJs 告警弹窗
- 虚拟机下安装Red Hat Linux
- 获取tableView刷新完成状态
- R语言table显示不同向量因子用法
- Codeforces Round #333 (Div. 1) C
- c# 退出
- 机器人“十三五”规划成型
- mysql join与子查 询在联表查询数据情况下,谁的效率更高?
- FMDatabaseQueue嵌套查询导致卡死
- Hadoop Shell命令
- JS之模板技术(aui / artTemplate)