Ios 使用执行块正确异步获取

Ios 使用执行块正确异步获取,ios,core-data,Ios,Core Data,我继续读到,在使用核心数据时,我应该使用[\u context performBlock]:^…进行异步搜索。我一辈子都想不出的是如何订阅这个街区的结尾或完整事件。换句话说,在我的代码中,我在获取数据之前使用了UIActivityIndicatorView,并且我希望在检索数据后删除此视图。然而,我不明白如何正确地完成这一点。 在过去,我使用了dispatch\u async(dispatch\u get\u global\u queue(dispatch\u queue\u PRIORITY\

我继续读到,在使用核心数据时,我应该使用
[\u context performBlock]:^…
进行异步搜索。我一辈子都想不出的是如何订阅这个街区的结尾或完整事件。换句话说,在我的代码中,我在获取数据之前使用了
UIActivityIndicatorView
,并且我希望在检索数据后删除此视图。然而,我不明白如何正确地完成这一点。 在过去,我使用了
dispatch\u async(dispatch\u get\u global\u queue(dispatch\u queue\u PRIORITY\u DEFAULT,0),^{…
,然后实现

dispatch_async(dispatch_get_main_queue(), ^(void) { 
了解que何时完成后台处理。 我可能完全错了,但我提出了一个问题。我需要实现什么委托,或者我需要订阅什么方法。要知道我的获取何时完成,我刚刚在
performBlock:

同样,我的最终目标是在获取之前设置UIActivityIndicatorView可见,获取数据并将其设置回不可见。提前感谢你们提供的任何帮助

**update**
由于需要搜索大量记录,我需要异步进行搜索。我有大约195k条记录,因此当用户开始在搜索栏中键入字母时,如果我尝试在主线程中执行此操作,会有1到2秒的延迟。因此,我会抛出一个
UIActivityIndicatorView
a然后我在后台线程上进行搜索,完成后更新主线程

这是我用来完成这个的代码

@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];

                });
            });
        }];
    }
}

在我开始写我的回复后,你的问题似乎有了很大的改变

让我知道这是否有用-否则我将删除,因为它不再涉及您的问题


通常,根据我的观点和经验,第二个
nsfetchedresultscoontroller
是过分的

请注意,编写本文的前提是,您已经通过编程或使用故事板正确实现了
UISearchBar
UISearchDisplayController
的实例。如果您不确定,请阅读我写的一篇文章

当您在问题中使用
UISearchDisplayController
委托方法时,我假设您已针对
@界面
(即
)声明了您的预期用途

最后,对于我的答案,我更愿意实现以下代码,为实现
NSFetchedResultsController
的任何
UITableViewController
创建可靠的搜索方法

创建公共或私有属性(取决于您的要求)
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
delegate方法

- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
    [self setSearchResults:nil];
}

希望这能有所帮助。

Andrew感谢您的回复。我将尝试一下您的解决方案。您是对的,我戏剧性地更改了我的问题。已经6个小时了,我对我的问题感到更加沮丧。然而,我最大的问题是我需要异步执行此操作。原因是我不想锁定我的主线程。你对如何正确完成这项任务有什么建议吗?非常感谢。@Miguel一些问题…1.为什么要求你进行异步搜索?2.你的搜索是否超出了
NSFetchedResultsController
?3.请编辑你的问题以提供更多信息定义您试图实现的目标-例如,
NSFetchedResultsController
feeds
UITableViewController
数据源方法,并且您只需要从外部数据源获取FRC/下载记录的当前
fetchedObject
属性中的不相关/相关记录/记录Source???问题已更新我不需要获取不相关的记录,但有太多记录,ui往往会冻结1或2秒,因此我尝试从后台线程执行此操作的原因。我担心的是我可能没有正确执行此操作。@Miguel您是否考虑过或调查过对
NSFetchedResultsC的错误处理ontroller
results而不是尝试后台获取?另一本书建议@Miguel…这是一本老书,但值得一读——迈克尔·普列瓦特和罗伯特·沃纳(即将被他们的新书《使用核心数据的Pro-iOS持久化》取代)的第7章,题为“优化性能和内存使用情况”。我建议您完成第7章中的教程。它将教您很多关于错误处理以及如何高效调用核心数据堆栈的知识。虽然我更喜欢Zarra风格的核心数据代码,但这本相对古老的Privat/Warner书采用了一种实用的方法来教育读者,我发现这对读者非常有帮助。