我继续读到在使用核心数据时我应该使用[_context performBlock]:^...
进行异步搜索。我无法想象我的生活是如何订阅结束或完整的事件谈论这个块。换句话说,在我的代码中,我在获取数据之前使用UIActivityIndicatorView
,并且我想在检索数据后删除此视图。但是,我不明白如何正确地实现这一目标。
在过去,我使用了dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{...
然后实现了
dispatch_async(dispatch_get_main_queue(), ^(void) {
知道que何时完成后台处理。
我可能完全错了,但我想问我这个问题。我需要实现什么代理或者我需要订阅什么方法。要知道我的提取完成时间,我刚刚在performBlock:
我的最终目标是在获取之前设置UIActivityIndicatorView,获取数据并将其设置为不可见。提前感谢你们提供的任何帮助。
**update**
我需要异步进行搜索,因为我必须搜索大量记录。我有大约195k的记录,所以当用户开始在搜索栏中输入字母时,如果我尝试在主线程中执行此操作,则会有1到2秒的延迟。因此我抛出一个UIActivityIndicatorView
然后我在后台线程上进行搜索并在我完成时更新主线程的原因。
这是我用来编写此代码的代码。
@property (strong, nonatomic) NSArray *filteredLocations;
@property (strong, nonatomic) NSArray * locationsFiltered;
//returns the search for this particular search.
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller
shouldReloadTableForSearchString:(NSString *)searchString
{
if ([searchString length ]>= 3) {
[self searchForText:searchString];
return YES;
}
else{
self.filteredLocations = nil;
return NO;
}
//return YES;
}
- (void)searchForText:(NSString *)searchText
{
if (self.context && self.isSearching == FALSE)
{
//[searchController ]
//[self.searchDisplayController.searchResultsTableView.]
self.isSearching = TRUE;
NSString *predicateFormat = @"%K BEGINSWITH[cd] %@ and state ==%@";
NSString *searchAttribute = @"name";
self.filteredLocations = nil;
NSPredicate *predicate = [NSPredicate predicateWithFormat:predicateFormat, searchAttribute, searchText,Searchstate];
[self.searchFetchRequest setPredicate:predicate];
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
if (self.spinnerShowing ==FALSE) {
spinner.center = CGPointMake(160, 190);
spinner.hidesWhenStopped = YES;
spinner.color = [UIColor grayColor];
[self.view addSubview:spinner];
//self.spinnerShowing = ;
[spinner startAnimating];
}
[_context performBlock:^(void){
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSError *error = nil;
self.filteredLocations = [self.managedObjectContext executeFetchRequest:self.searchFetchRequest error:&error];
NSLog(@"this is how many items are in the filtered locations at this time %i", [_filteredLocations count]);
if (error)
{
NSLog(@"searchFetchRequest failed: %@",[error localizedDescription]);
}
dispatch_async(dispatch_get_main_queue(), ^(void) {
NSLog(@"stopping the spinner now.");
self.spinnerShowing = FALSE;
[spinner stopAnimating];
[spinner hidesWhenStopped];
self.isSearching = FALSE;
//self.searchDisplayController.searchResultsTableView.hidden = NO;
// [searchController reloadData];
[self.searchDisplayController.searchResultsTableView reloadData];
});
});
}];
}
}
答案 0 :(得分:1)
在我开始撰写回复后,您似乎已经明显改变了您的问题......
请告诉我这是否有用 - 否则我会删除,因为它不再与您的问题有关。
一般来说,在我看来,第二次NSFetchedResultsController
是过度的。
请注意,这是基于您已经以编程方式或使用故事板正确实现UISearchBar
和UISearchDisplayController
的实例。如果您不确定,请阅读我写的previous answer可能会有所帮助。
当您在问题中使用UISearchDisplayController
委托方法时,我会假设您已针对@interface
(即<UISearchBarDelegate, UISearchDisplayDelegate>
)声明了您的预期用途。
最后我的回答,我更愿意实现以下代码,为实现UITableViewController
的任何NSFetchedResultsController
创建可靠的搜索方法...
创建公共或私有财产(取决于您的要求)NSMutableArray
以保存搜索结果的内容:
@property (nonatomic, retain) NSMutableArray *searchResults;
在以下情况下,您可以使用此NSMutableArray
设置UITableViewController
数据源方法:
if (tableView == self.searchDisplayController.searchResultsTableView) {
//code for searchResultsTableView
}
然后我使用UISearchDisplayController
委托方法来控制self.searchController.searchResultsTableView
的任何活动实例。
这是最重要的一个......
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
// Set search predicate and filter array
if (searchString && searchString.length) {
// Your predicateFormat and searchAttribute
NSString *predicateFormat = @"%K BEGINSWITH[cd] %@ and state ==%@";
NSString *searchAttribute = @"name";
// My code
NSPredicate *searchPredicate = nil;
NSArray *fetchedObjects = nil;
NSMutableArray *arrayResults = nil;
[self.searchResults removeAllObjects];
searchPredicate = [NSPredicate predicateWithFormat:predicateFormat, searchAttribute, searchString, searchState];
fetchedObjects = self.fetchedResultsController.fetchedObjects;
arrayResults = [NSMutableArray arrayWithArray:[fetchedObjects filteredArrayUsingPredicate:searchPredicate]];
[self setSearchResults:arrayResults];
}
// Return YES to reload the search result table view
return YES;
}
PS-将您的Searchstate变量更改为searchState!
您可能还想实现以下UISearchDisplayController
委托方法。
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
[self setSearchResults:nil];
}
希望这有帮助。