reloadData同步问题

问题描述

| 所以这是我的问题。 在我的应用程序主页中,我有一个简单的UITableView,最多可以容纳3个部分,2个部分每个最多包含3个项目,第三个部分最多可以容纳6个项目。 每个部分都有一个与之关联的标头。 实际内容来自网络,我发出请求,服务器发送数据,我使用NSXMLParser解析响应,创建数组以保存每个部分的数据(3个数组),还创建另一个数组以保留对这些部分的引用必须显示。 然后,最后,我调用[myTableView reloadData]刷新内容并重绘表。 用户也可以自己刷新内容。为此,我正在使用“拉动刷新”机制,就像Facebook应用程序一样。 使用“推入刷新”刷新内容也最终调用了[myTableView reloadData]。 刷新内容时,我遇到了一个令人讨厌的崩溃,该表需要更改其布局(例如:该表当前包含所有3个部分,而在我reloadData之后,它将仅显示一个部分)。 我使用调试器来跟踪问题。这是我发现的: 用户将整个表格拉低约50像素,然后松开 动画开始,使表格“ up”适应表格显示在表格顶部的320x50视图,并显示一条“ Loading”消息和一个UIActivityIndi​​catorView动画。 刷新被触发,我在后台任务中提出一个新的Web服务请求,获取新数据,解析,更新数组,最后在主线程上执行reloadData 同时,在进行刷新时,我注意到UITableView STILL将委托消息发送给: tableView:viewForHeaderInSection: tableView:cellForRowAtIndexPath: 我认为发生这种情况是由于“刷新”动画使表“移动”并显示新的单元格/标题,因此可以进行上述调用。 问题是,这会导致可怕的崩溃,因为似乎同时修改了保存节数据的数组和节数组本身。 发生这种情况时,委托方法可能在错误的上下文中使用项/节的更新/尚未更新的数组。也就是说,之前 numberOfSectionsInTableView: tableView:numberOfRowsInSection: 有机会为更新后的阵列正确更新新结构。 我知道这是长话,没有任何代码示例,但是我认为,如果我已经知道了问题(至少希望如此),并且有人理解了我的观点,也许有人可以指出我的正确方向进行纠正这个同步问题。 谢谢阅读! 之后编辑: 我找到了问题所在。我的请求刷新机制使用了一个如下所示的stopLoading回调:
- (void)stopLoading 
{ isLoading = NO;
// Hide the header
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDelegate:self];
[UIView setAnimationDuration:0.3];
[UIView setAnimationDidStopSelector:@selector(stopLoadingComplete:finished:context:)];
self.myTableView.contentInset = UIEdgeInsetsZero;
[refreshArrow layer].transform = CATransform3DMakeRotation(M_PI * 2,1);
[UIView commitAnimations];
} 在某个时候,我将表的contentInset重置为UIEdgeInsetsZero。 这个事实以及在后台刷新返回到主线程后我在reloadData之前调用stopLoading的事实-在错误的时刻触发了错误的委托回调。 因此,这是在更改表的contentInset和reloadData之间的时间问题

解决方法

听起来您好像正在从不同的线程更新用于表视图的数据存储。这不是一个好主意-数据很容易进入不一致状态,并且您使用的容器可能也不是线程安全的。 正确的方法是仅从主线程更新此数据。另外,您可能想看看插入行等的方法,这使得很少需要完全重新加载。而且,如果由于新数据而只想更新一个单元,则只需刷新该单元即可。