NSRangeException при использовании Core Data Asynchronous UISearchDisplayController - PullRequest
1 голос
/ 11 июня 2011

Я асинхронно извлекаю данные, и я использовал это как руководство: http://deeperdesign.wordpress.com/2011/05/30/cancellable-asynchronous-searching-with-uisearchdisplaycontroller/

В

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString{    
//setup request / predicate etc...            
[self.searchQueue addOperationWithBlock:^{
             NSError *error;             
             self.matchingObjects = [self.managedObjectContext executeFetchRequest:request error:&error];
             [request release];

             [[NSOperationQueue mainQueue] addOperationWithBlock:^
              {
                  [self.searchDisplayController.searchResultsTableView reloadData];
              }];

     }];            
    // Return YES to cause the search result table view to be reloaded.
    return NO;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{    
        // Return the number of rows in the section.
        return [self.matchingObjects count];
}

Время от времени я получаю что-то кЭффект:

*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSArray objectAtIndex:]: index 0 beyond bounds for empty array'

Выдается на ивар matchObjects при доступе к нему для создания ячейки таблицы в:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

Сбой не происходит постоянно, просто кажетсяслучаться в случайных случаях.Я предполагаю, что где-то счетчик в массиве MatchingObjects возвращает определенное значение, которое изменяется и не обновляется.

Я не совсем уверен, как с этим справиться - искал это длячасов, я что-то упускаю?

1 Ответ

1 голос
/ 11 июня 2011

Я понял, что это было - заняло у меня некоторое время, но я снова посмотрел на пример, который я только что связал. Я обновлял iVar self.matchingObjects в фоновом потоке, что в некоторых случаях вызывало несоответствие между диапазоном массива, доступного в основном потоке, и фоновым потоком. Так, например, переменная, возможно, была обновлена ​​в фоновом потоке, и основной поток все еще может получать доступ к той части диапазона, которая больше не существует в переменной с момента ее обновления.

Исправлено, изменив мой код следующим образом:

 [self.searchQueue addOperationWithBlock:^
 {
    NSError *error;

    NSArray *results = [self.managedObjectContext executeFetchRequest:request error:&error];
    [request release];

    [[NSOperationQueue mainQueue] addOperationWithBlock:^
    {
       self.matchingObjects = results;
       [self.searchDisplayController.searchResultsTableView reloadData];
    }];

}];

Теперь результаты поиска загружаются во временный удерживающий массив с именем «results», и сначала в главном потоке обновляется matchObjects iVar, а затем перезапускается tableView. Таким образом, tableView всегда ссылается на массив, который никогда не изменяется при обращении к нему, поскольку tableView полагается на matchObjects для получения количества строк и данных.

...