UITableView数据不一致

时间:2012-10-17 23:38:06

标签: objective-c ios uitableview

我有一个由UITableView支持的NSArray

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
  return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
  return self.data.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
  static NSString *CellIdentifier = @"CellIdentifier";
  UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier:CellIdentifier];
  if (cell == nil) {
      cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];

  }
  id item = [self.data objectAtIndex:indexPath.row];
  cell.item = item;

  return cell;
}

非常标准。现在问题是reloadData会同步询问numberOfSectionsnumberOfRows,但会异步调用cellForRow。因此,有时,在调用cellForRowAtIndexPath时,数据数组已更改,因此[self.data objectAtIndex:indexPath.row]会出现超出范围的异常并导致应用程序崩溃。我该如何避免这种情况?

请注意,每次设置data数组时,我都会调用[self.tableView reloadData]

4 个答案:

答案 0 :(得分:0)

经常调用

cellForRowAtIndexPath(滚动等),你可以添加一行简单的代码来检查数据数组的大小是否小于请求的单元格。虽然这意味着您可能最终得到空白单元格。

我在两种方法上都设置了断点,右键单击断点 - > “编辑断点”并勾选“评估后自动继续”。然后点击“添加操作” - > “调试器命令”,然后键入“po data”或“po [data count]”。

每次遇到断点时,都会在调试控制台中打印有关数组的信息(不停止)。然后,您应该能够查看调试输出并查看它不同步的位置。添加一些NSLog语句来告诉您正在调用哪个方法等,并从那里开始工作。

答案 1 :(得分:0)

我认为避免这种情况的最佳方法是在数据更新时避免用户交互。也许您可以向用户显示“更新...”和活动指示器。

另一种方法是使用另一个数组来填充新数据,处理可以在单独的线程中完成,有时只能通过重新加载调用将其分配回数据源数组。还可以使用具有相同内容的屏幕而数据源数组发生了变化

答案 2 :(得分:0)

我使用的快速黑客,尝试这个,看看它是否适合你:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
  static NSString *CellIdentifier = @"CellIdentifier";
  UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier:CellIdentifier];
  if (cell == nil) {
      cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];

  }

  // -----------------------------------------------------------------
  // the magical line that prevents the table from fetching the data
  // -----------------------------------------------------------------
  if([indexPath row] < [self.data count])
  {

      id item = [self.data objectAtIndex:indexPath.row];
      cell.item = item;
  }

  return cell;
}

:d

答案 3 :(得分:0)

您应该存储一个不会被修改的本地数组。然后,当您的基本数组更改时,您可以安全地更新您的存储阵列。考虑使用内置的api Add rows to existing UITableView section

在表格视图中添加/删除单元格