多线程TableViewController

时间:2013-05-03 15:33:15

标签: iphone ios multithreading uitableview grand-central-dispatch

我最近在UITableViewController的{​​{1}}:

中遇到了崩溃
tableView:cellForRowAtIndexPath

代码:

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

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

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

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

tableView:cellForRowAtIndexPath:

这会导致该方法抛出断言异常并导致应用程序崩溃。

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

2 个答案:

答案 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上将始终更新消息,并且您的崩溃问题将得到解决