我最近在UITableViewController
的{{1}}:
tableView:cellForRowAtIndexPath
代码:
-[__NSArrayM objectAtIndex:]: index 10 beyond bounds for empty array
消息为Message* res = [messages objectAtIndex:indexPath.row]
。
发生崩溃是因为在NSMutableArray
方法中我尝试从消息数组中获取消息,但该数组可能已被其他线程更改。我的消息数组的刷新是在另一个线程上完成的,这就是为什么我认为这发生了。
考虑到我需要继续使用多个线程,处理这种情况的最佳方法是什么?有没有办法取消单元格的绘制并强制重绘整个消息列表?我试图做一个简单的检查:
tableView:cellForRowAtIndexPath:
这会导致该方法抛出断言异常并导致应用程序崩溃。
目标是在发生这种情况时优雅地重新加载整个视图。
答案 0 :(得分:0)
在处理多线程时,必须非常小心地在后台线程和主线程之间以及UI更新时切换。当您尝试在线程完成之前更新UI时导致崩溃。让我举一个简短的例子,首先我们将在后台线程中调用一个方法
[self performSelectorInBackgroungThread:@selector(fetchDataFromServer)
withObject:nil
onCompletion:nil];
关注其他方法
-(void)fetchDataFromServer{
//Some something
[self performSelectorOnMainthread:@selector(backgroundThreadCompleted)]
withObject:nil
waitUntilDone:nil];
}
在后台线程中的工作完成后不久,我在主线程中调用一个方法,并仅在该方法中执行与UI更新相关的所有工作
-(void)backgroundThreadCompleted
{
//UI Updation
}
如果您遵循相同的流程,您的应用程序不会崩溃。在你的情况下,你试图访问一个空数组(任何索引不存在的对象)。作为预防步骤,如果[数组计数]!= 0,则执行条件检查,然后只尝试访问其他数组返回; 。当数组更改的值使用[UITableView reloadData]重新加载tableview时。
答案 1 :(得分:0)
如果您在消息数组中进行了更改,则必须重新加载tableView。 通过使用此消息,您的tableVlew上将始终更新消息,并且您的崩溃问题将得到解决