分类:iphone开发2011-11-25
15:541054人阅读收藏举报
UITableView reloadData的正确方法。
相信很多人会遇到这种情况,当tableView正在滚动的时候,如果reloadData,偶尔发生Appcrash的情况。 这种情况有时候有,有时候没有,已经难倒了很多人。直至今天,我在stackoverflow上面,仍没有发现真正有说到其本质的帖子。我的处女贴,选择这个问题来阐述一下我的观点。
小弟我英语很好,一般都是用英语记笔记,当然,我知道,论坛愤青很多,如果只贴英文出来,肯定找骂。 故简单翻译一下,以显示我的诚意。 原英文笔记附在后面。 请大家不要挑英语语法错误了,笔记就是笔记,不是出书。
第一句话,阐述问题的本质:在tableView的dataSource被改变 和 tableView的reloadData被调用之间有个时间差,而正是在这个期间,tableView的delegate方法被调用,如果新的dataSource的count小于原来的dataSource count,crash就很有可能发生了。
下面的笔记提供了两种解决方案,和记录了一个典型的错误,即 在background thread中修改了datasource,虽然调用[self.tableViewperformSelectorOnMainThread:@selector(reloadData)withObject:nilwaitUntilDone:NO];
记住正确的原则:Always change the dataSourceand(注意这个and)reloadData in the mainThread. What's more, reloadData should be calledimmediatelyafter the dataSource change.
If dataSource is changed but tableView's reloadData method is not called immediately, the tableView may crash if it's in scrolling.
Crash Reason:There is still a time gap between the dataSource change and reloadData. If thetableis scrolling during the time gap, the app may Crash!!!!
WRONG WAY:
Following codes is WRONG: even the reloadData is called in main thread, there is still a time gap between the dataSource change and reloadData. If the table is scrolling during the time gap, the app may Crash!!!!
wrong codes samples:
-(void) changeDatasource_backgroundThread
{
@autoreleasepool{
[self.dataSourceArrayremoveAllObjects];
[self.tableViewperformSelectorOnMainThread:@selector(reloadData)withObject:nilwaitUntilDone:NO];
}
}
RIGHT WAY:
Principle: Always change dataSource inMAINthread and call the reloadDataimmediatelyafter it.
Option 1:If the operation to change the dataSource should be executed in background, the operation can create a temp dataSource array and pass it to main thread with notification, the main thread observes the notification, assign
the tmpDataSource to dataSource and reload the tableView by reloadData.
Option 2:In the background, call the GDC dispatch_async to send the two methods to main threadtogether.
dispatch_async(dispatch_get_main_queue(), ^{
self.dataSourceArray= a new Array.
[self.tableView reloadData];
});
UITableView reloadData的正确方法。
相信很多人会遇到这种情况,当tableView正在滚动的时候,如果reloadData,偶尔发生Appcrash的情况。 这种情况有时候有,有时候没有,已经难倒了很多人。直至今天,我在stackoverflow上面,仍没有发现真正有说到其本质的帖子。我的处女贴,选择这个问题来阐述一下我的观点。
小弟我英语很好,一般都是用英语记笔记,当然,我知道,论坛愤青很多,如果只贴英文出来,肯定找骂。 故简单翻译一下,以显示我的诚意。 原英文笔记附在后面。 请大家不要挑英语语法错误了,笔记就是笔记,不是出书。
第一句话,阐述问题的本质:在tableView的dataSource被改变 和 tableView的reloadData被调用之间有个时间差,而正是在这个期间,tableView的delegate方法被调用,如果新的dataSource的count小于原来的dataSource count,crash就很有可能发生了。
下面的笔记提供了两种解决方案,和记录了一个典型的错误,即 在background thread中修改了datasource,虽然调用[self.tableViewperformSelectorOnMainThread:@selector(reloadData)withObject:nilwaitUntilDone:NO];
记住正确的原则:Always change the dataSourceand(注意这个and)reloadData in the mainThread. What's more, reloadData should be calledimmediatelyafter the dataSource change.
If dataSource is changed but tableView's reloadData method is not called immediately, the tableView may crash if it's in scrolling.
Crash Reason:There is still a time gap between the dataSource change and reloadData. If thetableis scrolling during the time gap, the app may Crash!!!!
WRONG WAY:
Following codes is WRONG: even the reloadData is called in main thread, there is still a time gap between the dataSource change and reloadData. If the table is scrolling during the time gap, the app may Crash!!!!
wrong codes samples:
-(void) changeDatasource_backgroundThread
{
@autoreleasepool{
[self.dataSourceArrayremoveAllObjects];
[self.tableViewperformSelectorOnMainThread:@selector(reloadData)withObject:nilwaitUntilDone:NO];
}
}
RIGHT WAY:
Principle: Always change dataSource inMAINthread and call the reloadDataimmediatelyafter it.
Option 1:If the operation to change the dataSource should be executed in background, the operation can create a temp dataSource array and pass it to main thread with notification, the main thread observes the notification, assign
the tmpDataSource to dataSource and reload the tableView by reloadData.
Option 2:In the background, call the GDC dispatch_async to send the two methods to main threadtogether.
dispatch_async(dispatch_get_main_queue(), ^{
self.dataSourceArray= a new Array.
[self.tableView reloadData];
});
分享到:
相关推荐
源码ZYTabelViewLoadAnimationDemo,该源码案例是一个tableView reloadData动画(swift),导入UITabelView+LoadAnimation.swift 然后在用reloadData方法的地方调用 /** * UITableView重新加载动画 * * @param ...
使用起来非常简单的,不需要alloc出某个类,整个流程仅需几行代码 //1.在开启下拉或者上拉前调用 [self.tableView setup]; //2.... [self.tableView setPullDownEnable:YES];... [self.tableView reloadData];
tableview手动适应cell高度,以及iOS8之后自动适应cell高度
之前一直做Cocos2dx开发的TableView用得比较多,自己也扩展了一些功能,新公司用的Creator,所以翻译了个ts版本的,核心代码和函数名与cocos2dx的一致。 例子:...
UITableView 数据为空时候的提示占位图,主要应用于网络出现错误的时候、数据源为空的时候。 __weak typeof(self)... [weakSelf.tableView reloadData]; }; https://github.com/tengshuq/TableViewPlaceholder
// alloc MLSelectPhotoPickerViewController *pickerVc = [[MLSelectPhotoPickerViewController alloc] init]; // Default Push CameraRoll pickerVc.status = ... [weakSelf.tableView reloadData]; }
[self.tableView reloadData];}];普通选择[[SCPhotoHelper sharedInstance] choosePicture:^(NSArray *assets) { [self.assets addObjectsFromArray:assets]; [self.tableView reloadData];}];图片浏览...
该源码案例是一款不错的类似微信的效果图片效果,源码MLSelectPhoto,类似微信的效果,效果实现也比较简单的,希望这个能够帮到大家的学习和使用。 使用代码 ... [weakSelf.tableView reloadData]; }
WXRedEnvelopes tableView reloadData时候,自动打开并抢红包; 红包详情页打开后自动关闭; 大的功能没有,抢是没问题的,仅供测试;
我们可以轻松做到这一点: self.resultsBinding = [ Bind ( self .dataStore, results) next: ^( id value) { [ self .tableView reloadData ];}]; 但是,如果您正在加载评论视图,并且还想用进来的商品计数来更新...
刷新TableView时动画加载cell ######将文件加入项目,导入头文件 UITableView+Extension.h UITableView+Extension.m #import "UITableView+Extension.h" ######需要刷新TableView时使用以下代码即可 [self.tableView ...
今天在review代码的时候发现之前的tableview 和 collectview 的分页加载逻辑还有优化的余地,于是进行了优化。... [strongSelf.tableView reloadData]; 优化之后的代码如下: NSMutableArray *indexPaths = [N
// 要做.. PickerViewController *pickerVc = [[PickerViewController alloc] init]; pickerVc.delegate = self; [self presentViewController:pickerVc 动画:YES 完成:nil];... [self.tableView reloadData]; }
ML相机 一个简单的多镜头相机。 可可豆 pod search 'MLCamera' ... [weakSelf.tableView reloadData]; }; [self presentViewController:cameraVc animated:YES completion:nil]; 接触 @: 执照 MLSelectPhoto
CocoRongPullToRefresh 喜欢这个项目吗? Star us above! 刷新刷新是所有应用程序中最常使用的功能之一,此组件提供了一种最简单的方法来为表视图添加刷新刷新功能。... reloadData () // Finish refresh
该效果的实现主要是使用runtime的交叉方法实现,将tableView的reloadData与自定义的kk_reloadData交换。新建tableView的Category。 交换方法主要代码 + (void)swizzleInstanceSelector:(SEL)originalSel ...
表格翻转(╯°□°)╯︵┻━┻┬──┬ノ(゜-゜ノ)动画很酷。 UITableView不是。 那么,为什么不使UITableView... reloadData ()self . tableView . animate ( animation : myCoolCellAnimation)而且,如果您想一次
[self.tableView reloadData]; } } failureBlock:^(NSError *error) { UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"提示" message:@"访问相册失败" delegate:self cancelButtonTitle:@...
部分更新,不再需要调用reloadData 平稳更快。 如果更改计数大于300,则使用非动画更新。 简化用法 我们可以在每个部分使用不同的类型。 类型安全我们可以通过IndexPath来获取类型明确的对象。 对列表UI使用...
搜索“UITableView 自动布局 加载数据 reloadData 跳动”之类的关键字,搜出来的是手动布局下设置estimatedRowHeight = 0;自动布局下在VC中增加一个字典来缓存indexPath对应的高度之类的答案。 成员变量 private ...