Crash when calling UITableView's reloadData too soon after each other
cocoa-touch, objective-c, uitableview
Solution
The assigment of the new data source array for the table view must also be done on the main thread, something like:
- (IBAction)personNameChanged:(UITextField *)sender
{
NSString *name = sender.text;
[backgroundThread performBlock:^{
// Store filtered array into separate array here:
NSArray *filteredPersons = [self.personsDataSource filterDataSourceByName:name];
[mainThread performBlock:^{
// Assign to table view data source array here:
self.dataSourceArray = filteredPersons;
[self.autoCompleteTableView reloadData];
}];
}];
}
Otherwise it can happen that the data source array is modified on the background thread while being accessed by the table view on the main thread.
Problem
I have a text field that show a table view of suggestions as the user types a name. The filtering of the data source is made in a background thread because it can take some time. ``` - (IBAction)personNameChanged:(UITextField *)sender { NSString *name = sender.text; [backgroundThread performBlock:^{ [self.personsDataSource filterDataSourceByName:name]; [mainThread performBlock:^{ [self.autoCompleteTableView reloadData]; }]; }]; } ``` `[UITableView reloadData]` calls: - `-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section` ...synchronously while all cells: - `- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath` ...are called at a later point in time. The problem is when the user is typing fast it can happen that `filterDataSourceByName` is called before all cells have loaded. Then `cellForRowAtIndexPath` is called for an indexPath that doesn't exist. How should you solve this problem when calling reloadData too fast so that is hasn't loaded all cells from the last reload?