0

我最近在UITableViewController's遇到了崩溃tableView:cellForRowAtIndexPath

-[__NSArrayM objectAtIndex:]: index 10 beyond bounds for empty array

对于代码:

Message* res = [messages objectAtIndex:indexPath.row]

消息是一个NSMutableArray.

发生崩溃是因为在该tableView:cellForRowAtIndexPath:方法中我尝试从消息数组中获取消息,但该数组可能已被其他线程更改。我的消息数组的刷新是在另一个线程上完成的,这就是我认为发生这种情况的原因。

考虑到我需要继续使用多个线程,处理这种情况的最佳方法是什么?有没有办法取消单元格的绘制并强制重绘整个消息列表?我试图做一个简单的 if 检查:

if([messages size] < indexPath.row) {
    return nil;
}

这会导致该方法引发断言异常并使应用程序崩溃。

目标是在发生这种情况时优雅地重新加载整个视图。

4

2 回答 2

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
 }

如果您遵循相同的流程,您的应用程序将不会崩溃。在您的情况下,您正在尝试访问一个空数组(任何索引处不存在的对象)。作为预防步骤,请执行条件检查,如果 [array count]!=0 则仅尝试访问其他数组返回; . 当数组的值改变时,使用 [UITableView reloadData] 重新加载你的 tableview。

于 2013-05-03T16:07:08.250 回答
0

当您在消息数组中进行更改时,您必须重新加载 tableView。通过使用它,您的消息将始终在您的 tableVlew 上更新,并且您的崩溃问题将得到解决

于 2013-05-03T17:04:12.457 回答