Reputation: 6106
I'm running into index beyond bounds exception in one of my UITableViews
and I think it could be down to some multithreading issues. Here's what I believe is happening:
UITableView
and it's data source is a regular NSMutableArray
.NSMutableArray
which is backing my UITableView
is updated every couple of seconds with the contents of an API response.UITableView
's reloadData is being invoked to ensure that the user sees new data from the API server.Here's my code:
-(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
Basically, I get an exception while trying to access an object in the betEvents structure at index 0.
What I believe is happening is:
reloadData
is called on the UITableView
numberOfSectionsInTableView:
is invoked which returns a value > 0.UITableView
's data source.cellForRowAtIndexPath:
is invoked and it bombs.Is there any way to ensure that this doesn't happen? Do I need to start using some primitive locks on the data source to ensure that it doesn't get updated while the table is being updated?
EDIT Took another look at how the data structures returned by currentBetEvents can be altered and it looks like the filteredBets & betEvents can be cleared out as a result of the following code:
[[NSNotificationCenter defaultCenter] postNotificationName:kUserLoggedOutNotification object:nil];
This notification is posted whenever the user logs out. Whenever a user logs out of the app, I need to clear out the filteredBets and betEvents arrays. Is it possible that the following could happen:
reloadData
is called on the UITableView
numberOfSectionsInTableView:
is invoked which returns a value > 0.cellForRowAtIndexPath:
is invoked and it bombs.Thanks,
Sean
Upvotes: 1
Views: 442
Reputation: 57139
Definitely sounds like a threading problem. You might try something like this:
// view controller
@synchronized([[BFOpenBetsModel sharedInstance] betEvents])
{
[self.tableView reloadData];
}
…
// data model
@synchronized(_betEvents) // or whatever the instance variable -betEvents returns is
{
[_betEvents addObject:whatever];
}
Upvotes: 2