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?

Original source