2012-11-08 37 views
1

我正在运行到索引超出范围例外之一,在我的UITableViews和我认为它可能归结为一些多线程问题。这就是我认为正在发生的事情:UITableViewDataSource和多线程

  1. 我有一个UITableView和它的数据源是一个普通NSMutableArray
  2. 这个支持我的UITableViewNSMutableArray每隔几秒就会更新一次API响应的内容。
  3. 每次更新后,都会调用UITableView的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 

基本上,我得到一个异常,而试图在索引来访问betEvents结构的对象0

相信的情况是:

  1. reloadData被调用UITableView
  2. numberOfSectionsInTableView:被调用,返回的值大于0.
  3. 胭脂线程到达并清除了UITableView的数据源。
  4. cellForRowAtIndexPath:被调用并炸弹。

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


编辑 拿了再看看由currentBetEvents返回的数据结构可以如何改变,它看起来像filteredBets & betEvents可以如下面的代码,结果被清除出:

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

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

  1. reloadData被呼吁UITableView
  2. numberOfSectionsInTableView:调用它返回一个值> 0
  3. 用户注销揭开序幕通知&送走数据结构。
  4. cellForRowAtIndexPath:被调用并炸弹。

感谢,

肖恩

+0

你正在实现numberOfRowsInTableView? – rdelmar

+1

我认为你需要展示betEvents如何得到更新,以及你如何通知表视图它需要更新。 – rdelmar

+0

rdelmar - 我没有实现numberOfRowsInTableView。只需numberOfRowsInSection和numberOfSectionsInTableView。编辑我的答案,以包含更多关于赌注数组如何更新的更多信息。谢谢。 – seanoshea

回答

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]; 
} 
+0

嗨,诺亚。由于NSTableView绘图正在主UI线程上进行,我是否可以确保所有对bet事件的编辑都在主UI线程上执行? – seanoshea

+0

这也可以起作用,但总的来说,您不想在主线程上执行任何数据,因为它可能会伤害您的应用程序的响应速度。 –