我在執行GCD時在我的UISearchDisplayController中顯示來自Core Data的結果時遇到問題。沒有它,它可以工作,但顯然會阻止用戶界面。使用GCD核心數據結果更新UISearchDisplayController
在我SearchTableViewController我有以下兩種方法:
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
// Tell the table data source to reload when text changes
[self filterContentForSearchText:searchString];
// Return YES to cause the search result table view to be reloaded.
return YES;
}
// Update the filtered array based on the search text
-(void)filterContentForSearchText:(NSString*)searchText
{
// Remove all objects from the filtered search array
[self.filteredLocationsArray removeAllObjects];
NSPredicate *predicate = [CoreDataMaster predicateForLocationUsingSearchText:@"Limerick"];
CoreDataMaster *coreDataMaster = [[CoreDataMaster alloc] init];
// Filter the array using NSPredicate
self.filteredLocationsArray = [NSMutableArray arrayWithArray:
[coreDataMaster fetchResultsFromCoreDataEntity:@"City" UsingPredicate:predicate]];
}
你可能已經猜到了,我的問題是與返回從[coreDataMaster fetchResultsFromCoreDataEntity]數組。下面是方法:
- (NSArray *)fetchResultsFromCoreDataEntity:(NSString *)entity UsingPredicate:(NSPredicate *)predicate
{
NSMutableArray *fetchedResults = [[NSMutableArray alloc] init];
dispatch_queue_t coreDataQueue = dispatch_queue_create("com.coredata.queue", DISPATCH_QUEUE_SERIAL);
dispatch_async(coreDataQueue, ^{
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entityDescription = [NSEntityDescription
entityForName:entity inManagedObjectContext:self.managedObjectContext];
NSSortDescriptor *nameSort = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObjects:nameSort, nil];
[fetchRequest setEntity:entityDescription];
[fetchRequest setSortDescriptors:sortDescriptors];
// Check if predicate is set
if (predicate)
{
[fetchRequest setPredicate:predicate];
}
NSError *error = nil;
NSArray *fetchedManagedObjects = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
for (City *city in fetchedManagedObjects)
{
[fetchedResults addObject:city];
}
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:[NSArray arrayWithArray:fetchedResults] forKey:@"results"];
[[NSNotificationCenter defaultCenter]
postNotificationName:@"fetchResultsComplete"
object:nil userInfo:userInfo];
});
return [NSArray arrayWithArray:fetchedResults];
}
所以線程還沒有完成執行時,它返回結果self.filteredLocationsArray。我已經嘗試添加一個NSNotification其經過的NSDictionary該方法:
- (void)updateSearchResults:(NSNotification *)notification
{
NSDictionary *userInfo = notification.userInfo;
NSArray *array = [userInfo objectForKey:@"results"];
self.filteredLocationsArray = [NSMutableArray arrayWithArray:array];
[self.tableView reloadData];
}
我也嘗試刷新searchViewController等
[self.searchDisplayController.searchResultsTableView reloadData];
但無濟於事。如果有人能指引我朝着正確的方向,告訴我我可能會出錯的地方,我會非常感激。
感謝
編輯
我只是想澄清克里斯托弗的供將來參考解決方案的東西。
當我調用這個方法時,我把GCD調用放到競爭塊的主隊列中。還要注意重新加載tableView的改變。
例
[coreDataMaster fetchResultsFromCoreDataEntity:(NSString *)entity usingPredicate:(NSPredicate *)predicate completionHandler:^(NSArray *cities){
dispatch_async(dispatch_get_main_queue(), ^{
self.filteredLocationsArray = cities;
[self.searchDisplayController.searchResultsTableView reloadData];
});
}];
以供將來參考回答這個問題是相關的http://stackoverflow.com/questions/3903718/uisearchdisplaycontoller-cant-prevent-table-reload-on-typing-in-search-酒吧/ 5342989#5342989。 –