简体   繁体   中英

Strange objectAtIndex beyond bounds error in UITableView

I am implementing a search keywords history with predicate in a UITableView .

I allocate and init a NSMutableArray object filteredHistory in viewDidLoad. This array gets filled when I type something on the search bar (using the TextDidChange method in UISearchBar ).

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
    [self filterContentForSearchText:searchText];
    [self.searchKeywordTableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];
    LogDebug(@"Filtered history count: %d", self.filteredHistory.count);
}

I use the method like this to filter:

- (void)filterContentForSearchText:(NSString*)searchText
{
    [self.filteredHistory removeAllObjects]; // First clear the filtered array.
    for (MyObject *searchKeyword in self.searchHistory)
    {
        NSPredicate *predicate = [NSPredicate predicateWithFormat:
                                  @"(SELF contains[cd] %@)", searchText];
        [searchKeyword.name compare:searchText options:NSCaseInsensitiveSearch];
        BOOL resultName = [predicate evaluateWithObject:searchKeyword.name];
        if(resultName)
        {
            [self.filteredHistory addObject:searchKeyword];
        }
    }
}

Then reload the UITableView in TextDidChange .

In tableView numberOfRowsInSection: method

return self.filteredHistory.count;

in my cellForRowAtIndexPath method I have:

LogDebug(@"Current row = %d", indexPath.row);
MyObject search = [self.filteredHistory objectAtIndex:indexPath.row];

Then after I tested for a few times the app crashes with an error saying:

[__NSArrayM objectAtIndex:]: index 10 beyond bounds [0 .. 9]'

I checked the filteredHistory and the count is 10. Strange thing is in the first few attempts when I typed in the same text in the searchbar there was no problem. In my debug code I could see the count was 10 and the table view displayed the filtered search results from index 0 to 9. I couldn't understand why suddenly the index of filteredHistory is beyond bounds [0..9]? When the code went smoothly, the LogDebug method print out MyObject from index 0 to 9. However when it crashes, it only prints out "Current row = 10".

performSelectorOnMainThread with waitUntilDone:NO here:

[self.searchKeywordTableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];

does not call the method immediately, but later as part of the normal run loop processing. It could therefore happen that cellForRowAtIndexPath is called after you have filtered the array, but before reloadData is called.

You should replace that line with an immediate call

[self.searchKeywordTableView reloadData];

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM