`
dowhathowtodo
  • 浏览: 779189 次
文章分类
社区版块
存档分类
最新评论

tableview的reloadData应注意 tableview的reloadData应注意

 
阅读更多

tableview的reloadData应注意

分类:iphone开发1054人阅读评论(0)收藏举报
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];
});


分享到:
评论

相关推荐

    tableView reloadData动画(swift)

    源码ZYTabelViewLoadAnimationDemo,该源码案例是一个tableView reloadData动画(swift),导入UITabelView+LoadAnimation.swift 然后在用reloadData方法的地方调用 /** * UITableView重新加载动画 * * @param ...

    ios-封装UITableView下拉和上拉.zip

    使用起来非常简单的,不需要alloc出某个类,整个流程仅需几行代码 //1.在开启下拉或者上拉前调用 [self.tableView setup]; //2.... [self.tableView setPullDownEnable:YES];... [self.tableView reloadData];

    tableview自适应cell高度

    tableview手动适应cell高度,以及iOS8之后自动适应cell高度

    Cocos Creator TableView.ts 翻译 Cocos2dx cc.TableView

    之前一直做Cocos2dx开发的TableView用得比较多,自己也扩展了一些功能,新公司用的Creator,所以翻译了个ts版本的,核心代码和函数名与cocos2dx的一致。 例子:...

    ios-UITableViewPlaceholder.zip

    UITableView 数据为空时候的提示占位图,主要应用于网络出现错误的时候、数据源为空的时候。 __weak typeof(self)... [weakSelf.tableView reloadData]; }; https://github.com/tengshuq/TableViewPlaceholder

    ios-微信相册选择器.zip

    // alloc MLSelectPhotoPickerViewController *pickerVc = [[MLSelectPhotoPickerViewController alloc] init]; // Default Push CameraRoll pickerVc.status = ... [weakSelf.tableView reloadData]; }

    CF_PhotoHelperDemo:基于MLSelectPhoto的图片多选,相册,手机拍照

    [self.tableView reloadData];}];普通选择[[SCPhotoHelper sharedInstance] choosePicture:^(NSArray *assets) { [self.assets addObjectsFromArray:assets]; [self.tableView reloadData];}];图片浏览...

    类似微信的效果图片效果

    该源码案例是一款不错的类似微信的效果图片效果,源码MLSelectPhoto,类似微信的效果,效果实现也比较简单的,希望这个能够帮到大家的学习和使用。 使用代码 ... [weakSelf.tableView reloadData]; }

    WXRedEnvelopes:抓住 WX 红包

    WXRedEnvelopes tableView reloadData时候,自动打开并抢红包; 红包详情页打开后自动关闭; 大的功能没有,抢是没问题的,仅供测试;

    Binding:iOS的轻量级绑定

    我们可以轻松做到这一点: self.resultsBinding = [ Bind ( self .dataStore, results) next: ^( id value) { [ self .tableView reloadData ];}]; 但是,如果您正在加载评论视图,并且还想用进来的商品计数来更新...

    UITableViewReloadAnimation:刷新TableView时动画加载cell

    刷新TableView时动画加载cell ######将文件加入项目,导入头文件 UITableView+Extension.h UITableView+Extension.m #import "UITableView+Extension.h" ######需要刷新TableView时使用以下代码即可 [self.tableView ...

    iOS 高效的分页加载实现示例

    今天在review代码的时候发现之前的tableview 和 collectview 的分页加载逻辑还有优化的余地,于是进行了优化。... [strongSelf.tableView reloadData]; 优化之后的代码如下: NSMutableArray *indexPaths = [N

    ZLAssetsPickerDemo:相册多选功能

    // 要做.. PickerViewController *pickerVc = [[PickerViewController alloc] init]; pickerVc.delegate = self; [self presentViewController:pickerVc 动画:YES 完成:nil];... [self.tableView reloadData]; }

    MLCamera:一个简单的自定义连拍相机

    ML相机 一个简单的多镜头相机。 可可豆 pod search 'MLCamera' ... [weakSelf.tableView reloadData]; }; [self presentViewController:cameraVc animated:YES completion:nil]; 接触 @: 执照 MLSelectPhoto

    CocoRongPullToRefresh:使用Swift编写的用于iOS的简单刷新刷新组件

    CocoRongPullToRefresh 喜欢这个项目吗? Star us above! 刷新刷新是所有应用程序中最常使用的功能之一,此组件提供了一种最简单的方法来为表视图添加刷新刷新功能。... reloadData () // Finish refresh

    ios UITableView实现无数据加载占位图片

    该效果的实现主要是使用runtime的交叉方法实现,将tableView的reloadData与自定义的kk_reloadData交换。新建tableView的Category。 交换方法主要代码 + (void)swizzleInstanceSelector:(SEL)originalSel ...

    TableFlip:一种更简单的制作UITableView动画的方法! (╯°□°)╯︵┻━┻

    表格翻转(╯°□°)╯︵┻━┻┬──┬ノ(゜-゜ノ)动画很酷。 UITableView不是。 那么,为什么不使UITableView... reloadData ()self . tableView . animate ( animation : myCoolCellAnimation)而且,如果您想一次

    相册多个图片选择

    [self.tableView reloadData]; } } failureBlock:^(NSError *error) { UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"提示" message:@"访问相册失败" delegate:self cancelButtonTitle:@...

    数据源:类型安全数据驱动的CollectionView,TableView Framework。 (我们也可以使用ASCollectionNode)

    部分更新,不再需要调用reloadData 平稳更快。 如果更改计数大于300,则使用非动画更新。 简化用法 我们可以在每个部分使用不同的类型。 类型安全我们可以通过IndexPath来获取类型明确的对象。 对列表UI使用...

    对使用自动布局的UITableView进行上拉加载更多操作时,tableView向上跳动一定的高度

    搜索“UITableView 自动布局 加载数据 reloadData 跳动”之类的关键字,搜出来的是手动布局下设置estimatedRowHeight = 0;自动布局下在VC中增加一个字典来缓存indexPath对应的高度之类的答案。 成员变量 private ...

Global site tag (gtag.js) - Google Analytics