所以这是我的问题。 在我的应用程序主页中,我有一个简单的UITableView,最多可容纳3个部分,2个部分,每个部分最多3个项目,第3个部分最多可容纳6个项目。
每个部分都有与之关联的标题。
实际内容来自web,我发出请求,服务器发送数据,我用NSXMLParser解析响应,创建数组以保存每个部分的数据(3个数组),并创建另一个数组以保持对我将不得不展示。
然后,最后,我调用[myTableView reloadData]来刷新内容和重绘表。 用户还可以自己刷新内容。为此,我正在使用像Facebook应用程序一样的拉动刷新机制。
使用pull-to-refresh刷新内容也最终调用[myTableView reloadData]。 当我刷新我的内容并且表需要更改其布局时,我遇到了令人讨厌的崩溃(例如:表当前包含所有3个部分,在我重新加载数据之后它将只显示一个部分)。
我使用调试器来追踪问题。这是我发现的:
我认为这是因为拉动刷新动画会“移动”表格并显示新的单元格/标题,从而调用上述内容。
问题是这会导致可怕的崩溃,因为保存数据的数组和部分数组本身会同时被修改。
发生这种情况时,委托方法可能会在错误的上下文中使用更新/尚未更新的项目/部分数组。也就是说,在
之前有机会为更新的数组正确更新新结构。
我知道没有任何代码示例的长篇故事,但我想如果我已经知道问题(至少我希望我这样做)并且如果有人看到我的观点,也许有人可以指出我正确的方向来纠正这个同步问题。
感谢阅读!
稍后编辑:
我发现了问题所在。我的pull-to-refresh机制使用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, 0, 0, 1);
[UIView commitAnimations];
}
在某些时候,我重置了我的表的contentInset,将其设置为UIEdgeInsetsZero。 这个以及在主线程上返回后台刷新后我在reloadData之前调用stopLoading的事实 - 在错误的时刻触发了错误的委托回调。
因此,在更改表的contentInset和reloadData之间存在时间问题。
答案 0 :(得分:0)
听起来您正在从不同的线程更新用于表视图的数据存储。这不是一个好主意 - 数据很容易进入不一致的状态,而您正在使用的容器可能不是线程安全的。
正确的方法是仅从主线程更新此数据。此外,您可能希望查看插入行等的方法,这使得很少需要完全重新加载。如果您只是想因新数据更新一个单元格,那么只需刷新该单元格即可。