tableview的reloadData应注意

http://blog.csdn.net/ouyangtianhan/article/details/7835041

http://stackoverflow.com/questions/16071503/how-to-tell-when-uitableview-has-completed-reloaddata

UITableView reloadData的正确方法。

相信很多人会遇到这种情况,当tableView正在滚动的时候,如果reloadData,偶尔发生App crash的情况。 这种情况有时候有,有时候没有,已经难倒了很多人。直至今天,我在stackoverflow上面,仍没有发现真正有说到其本质的帖子。我的处女贴,选择这个问题来阐述一下我的观点。
小弟我英语很好,一般都是用英语记笔记,当然,我知道,论坛愤青很多,如果只贴英文出来,肯定找骂。 故简单翻译一下,以显示我的诚意。 原英文笔记附在后面。 请大家不要挑英语语法错误了,笔记就是笔记,不是出书。

第一句话,阐述问题的本质:在tableView的dataSource被改变 和 tableView的reloadData被调用之间有个时间差,而正是在这个期间,tableView的delegate方法被调用,如果新的dataSource的count小于原来的dataSource count,crash就很有可能发生了。

下面的笔记提供了两种解决方案,和记录了一个典型的错误,即 在background thread中修改了datasource,虽然调用 [self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nilwaitUntilDone:NO];

记住正确的原则: Always change the dataSource and(注意这个and) reloadData in the mainThread. What‘s more, reloadData should be called immediately after 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 the table is 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.dataSourceArray removeAllObjects]; 
[self.tableViewperformSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];
    }
}

RIGHT WAY: 
Principle:  Always change dataSource in MAIN thread and call the reloadData immediately after 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 thread together.
dispatch_async(dispatch_get_main_queue(), ^{
        self.dataSourceArray= a new Array.
        [self.tableView reloadData];
});

时间: 2024-10-27 19:46:53

tableview的reloadData应注意的相关文章

tableView 注意点

1 1. 使用UITableView的"静态单元格". 2 (注意: 使用静态单元格, 必须使用UITableViewController控制器) 3 * 什么是静态单元格? 什么是动态单元格? 4 1> 静态单元格不会随着数据的改变而改变, 当在storyboard中设计的时候是什么样子, 最后运行效果就是什么样子, 并且不会随着数据的变化而变化.如果要想改变静态单元格内容, 必须重新修改代码. 5 2> 动态单元格在设计的时候只是将单元格的"框架(壳子)&qu

iOS中一个页面显示两个tableview的情况

一个页面显示两个tableview,并且每个tableview上的数据都不一样,一般用以下方法: 首先建一个继承自UIView的类,来表示用来切换tableview的view //在view的类的.h文件中 #import <UIKit/UIKit.h> @protocol MyAttentionHeadViewDelegate <NSObject> //建一个叫MyAttentionHeadViewDelegate的一个代理 @optional //两个代理方法(可选择实现opt

TableView的动态更新操作(无需重新加载数据源)

项目中我们经常会用到TableView展示一个Cell,Cell的数据来源于我们自定义的一个Model类,那么对于TableView我们有以下几种场景. 1. 添加操作: 在该列表页面顶部有一个按钮叫做新建,点击后进入一个新的添加页面,添加完成之后,返回到列表页更新数据. 2. 更新操作:点击列表中cell进入编辑页面,编辑页面其实就是这个Model类中属性的一个展示,对其中某些属性进行更改后,返回到列表页更新数据. 3. 删除操作:点击列表中cell进入编辑页面,该页面有个删除按钮,点击删除按

【iOS开发-59】LOL案例:单组tabView、alertView样式、实现监听,以及用reloadData数据刷新

案例效果: (1)先在storyboard中拖拽出一个tableView.然后下面用代码. --tableView继承自scrollView.所以自然有滚动的特性 --最基本的还是数据转模型,以及对cell的赋值 --而cell的赋值那一块,为了优化性能,我们先从tableView的缓存中查找有无被缓存的cell,假设有,直接取出,假设没有再创建.这样提高性能. --这个缓存池是tableView自带的,当滚动的时候,cell不在视线范围内时,这个cell就被放到缓存池里了. #import "

iOS深入学习(UITableView系列2:reloadData)

接着前一篇的博客来深入学习UITableView, UITableView的数据源是NSMutableArray的对象_infoArray,现在数组的内容为{@"Zero",@"One",@"Two",@"Three",@"Four"},如果数组的内容增加了,该怎样刷新UITableView界面的内容呢?答案是通过reloadData方法,下面我就来模拟一个场景,点击导航栏右侧的ButtonItem,向可变

UI 09 tableView 中国省市区. 一个页面, 三个tableView

感觉省市区要被玩坏了---. #import "MainViewController.h" #define WIDTH self.view.frame.size.width #define HEIGHT self.view.frame.size.height @interface MainViewController ()<UITableViewDataSource, UITableViewDelegate> @property (nonatomic,retain)NSMu

[iOS基础控件 - 6.9.3] QQ好友列表Demo TableView

A.需求 1.使用plist数据,展示类似QQ好友列表的分组.组内成员显示缩进功能 2.组名使用Header,展示箭头图标.组名.组内人数和上线人数 3.点击组名,伸展.缩回好友组 B.实现步骤 1.编写MVC结构 (1)根据plist文件结构,编写model,使用嵌套型 1 // 2 // FriendGroup.h 3 // FriendsList 4 // 5 // Created by hellovoidworld on 14/12/12. 6 // Copyright (c) 2014

【iOS基础控件 - 13】【Demo 】QQ好友列表TableView

A.需求 1.使用plist数据,展示类似QQ好友列表的分组.组内成员显示缩进功能 2.组名使用Header,展示箭头图标.组名.组内人数和上线人数 3.点击组名,伸展.缩回好友组 code source: B.实现步骤 1.编写MVC结构 (1)根据plist文件结构,编写model,使用嵌套型 1 // 2 // FriendGroup.h 3 // FriendsList 4 // 5 // Created by hellovoidworld on 14/12/12. 6 // Copyr

IOS设计模式之二(门面模式,装饰器模式)

本文原文请见:http://www.raywenderlich.com/46988/ios-design-patterns. 由 @krq_tiger(http://weibo.com/xmuzyq)翻译,如果你发现有什么错误,请与我联系谢谢. 门面(Facade)模式(译者注:facade有些书籍译为门面,有些书籍译为外观,此处译为门面) 门面模式针对复杂的子系统提供了单一的接口,不需要暴漏一些列的类和API给用户,你仅仅暴漏一个简单统一的API. 下面的图解释了这个概念: 这个API的使用者