1

我在其中一个中遇到了超出范围的索引异常,UITableViews认为这可能是由于一些多线程问题。这是我认为正在发生的事情:

  1. 我有一个UITableView,它的数据源是一个常规的NSMutableArray.
  2. NSMutableArray是支持我UITableView的,每隔几秒钟就会使用 API 响应的内容进行更新。
  3. 每次更新后,都会UITableView调用 's reloadData 以确保用户看到来自 API 服务器的新数据。
  4. 有时会引发索引超出范围异常。

这是我的代码:

-(NSMutableArray*) currentBetEvents
{
    return  currentMarketId == nil ? [[BFOpenBetsModel sharedInstance] betEvents] :     filteredBetEvents;
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{    
    NSArray *betEvents = [self currentBetEvents];
    return [betEvents count];
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSArray *betEvents = [self currentBetEvents];
    id obj = [betEvents objectAtIndex:indexPath.section] // this is where it blows up

基本上,我在尝试访问索引为 0 的 betEvents 结构中的对象时遇到异常。

相信正在发生的是:

  1. reloadData被称为UITableView
  2. numberOfSectionsInTableView:被调用,返回值 > 0。
  3. 一个胭脂线程到达并清除了UITableView的数据源。
  4. cellForRowAtIndexPath:被调用并爆炸。

有什么办法可以确保不会发生这种情况?我是否需要开始在数据源上使用一些原始锁以确保在更新表时不会更新它?


编辑 再看一下 currentBetEvents 返回的数据结构是如何被改变的,看起来filteredBets & betEvents 可以通过以下代码被清除:

[[NSNotificationCenter defaultCenter] postNotificationName:kUserLoggedOutNotification object:nil];

每当用户注销时都会发布此通知。每当用户退出应用程序时,我都需要清除 filtersBets 和 betEvents 数组。是否有可能发生以下情况:

  1. reloadData被称为UITableView
  2. numberOfSectionsInTableView:被调用,返回值 > 0。
  3. 用户注销会启动通知并清除数据结构。
  4. cellForRowAtIndexPath:被调用并爆炸。

谢谢,

肖恩

4

1 回答 1

2

绝对听起来像一个线程问题。你可以尝试这样的事情:

// view controller
@synchronized([[BFOpenBetsModel sharedInstance] betEvents])
{
    [self.tableView reloadData];
}

…

// data model
@synchronized(_betEvents) // or whatever the instance variable -betEvents returns is
{
    [_betEvents addObject:whatever];
}
于 2012-11-08T03:21:59.563 回答