2011-06-11 54 views
1

我異步獲取數據,並且我用這個作爲指導:http://deeperdesign.wordpress.com/2011/05/30/cancellable-asynchronous-searching-with-uisearchdisplaycontroller/NSRangeException

- (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]; 
} 

時不時地,我會找些東西這是在matchingObjects的ivar訪問它構造表單元格時拋出

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

:效果

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

碰撞不會一直髮生,似乎隨機發生。我猜在匹配對象數組的計數正在返回一個特定的值,這個值會改變並且不會被更新。

我不完全確定如何處理這個問題 - 一直在尋找這個小時,有什麼我失蹤?

回答

1

我想清楚它是什麼 - 花了我一段時間,但我又看了一下我剛剛鏈接的例子。我正在更新後臺線程中的self.matchingObjects iVar,這在某些情況下會導致主線程和後臺線程中可用數組的範圍不匹配。因此,例如,變量可能已在後臺線程中更新,並且主線程可能仍在訪問變量自從更新後不再存在的範圍的一部分。

通過修改我的代碼如下修正它:

[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]; 
    }]; 

}]; 

現在搜索的結果加載到名爲「結果」的臨時存放陣列,以及matchingObjects伊娃在主線程首先更新然後tableView被重新加載。這樣,tableView總是引用一個在訪問時從不改變的數組,因爲tableView依賴於匹配對象來獲取行數和數據。