Objective c 带搜索的NSFetchedResultsController

Objective c 带搜索的NSFetchedResultsController,objective-c,core-data,nsfetchedresultscontroller,Objective C,Core Data,Nsfetchedresultscontroller,过滤NSFetchedResultsController数据的最佳做法是什么? 我是否需要在每次搜索栏的文本更改时重新初始化它 我使用的是UISearchDisplayController,我正在实现: - (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString; Thx.显然,这是一种更好的方法

过滤
NSFetchedResultsController
数据的最佳做法是什么? 我是否需要在每次搜索栏的文本更改时重新初始化它

我使用的是
UISearchDisplayController
,我正在实现:

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString;

Thx.

显然,这是一种更好的方法:

- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
    self.savedSearchTerm = searchText;

    freshData = NO;
    if (searchText !=nil)
    {
            NSPredicate *predicate =[NSPredicate predicateWithFormat:@"name contains[cd] %@", searchText];
            [fetchedResultsController.fetchRequest setPredicate:predicate];
    }
    else
    {
            NSPredicate *predicate =[NSPredicate predicateWithFormat:@"All"];
            [fetchedResultsController.fetchRequest setPredicate:predicate];
    }

    NSError *error = nil;
    if (![[self fetchedResultsController] performFetch:&error]) {
            // Handle error
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            exit(-1);  // Fail
    }           

    [self.tableView reloadData];

    //    [searchBar resignFirstResponder];   
    //    [_shadeView setAlpha:0.0f];

 }

盖伊的答案代码和问题有什么不同?据我猜测,filterContentForSearchText:scope方法是由shouldReload方法调用的

无论如何,我在CoreDataBooks示例中添加了一些类似的代码来包含搜索。在IB中为CoreDataBooks示例添加搜索显示控制器。然后,我向RootViewController.m添加了如下代码:

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
 NSInteger searchOption = controller.searchBar.selectedScopeButtonIndex;
 return [self searchDisplayController:controller shouldReloadTableForSearchString:searchString searchScope:searchOption];
}

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption {
 NSString* searchString = controller.searchBar.text;
 return [self searchDisplayController:controller shouldReloadTableForSearchString:searchString searchScope:searchOption];
}

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString*)searchString searchScope:(NSInteger)searchOption {

 NSPredicate *predicate = nil;
 if ([searchString length])
  if (searchOption == 0) // full text, in my implementation.  Other scope button titles are "Author", "Title"
   predicate = [NSPredicate predicateWithFormat:@"title contains[cd] %@ OR author contains[cd] %@", searchString, searchString];
  else
   // docs say keys are case insensitive, but apparently not so.
   predicate = [NSPredicate predicateWithFormat:@"%K contains[cd] %@", [[controller.searchBar.scopeButtonTitles objectAtIndex:searchOption] lowercaseString], searchString];
 [fetchedResultsController.fetchRequest setPredicate:predicate];

    NSError *error = nil;
    if (![[self fetchedResultsController] performFetch:&error]) {
  NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
  abort();
    }           

 return YES;
}

另外,为了回答Vivas问题,它使用UISearchDisplayController自动创建一个新的表视图,以覆盖过滤列表。您可以检查正在使用的tableView,如文档所示,但在最简单的设置中,它之所以有效,是因为fetchedResultsController要么在搜索的表视图中显示过滤后的版本,要么在表视图中显示所有数据。

appl文档说不应更改获取请求,他们特别说不应更改谓词。@RogerNolan确定吗?退房这三个步骤对我来说很好,我甚至修改了fetch请求的谓词。无论哪种方式,基本上都是这样的:如果更改请求,则必须重新发出搜索。我已编辑示例以调用abort()而不是exit(-1)。正如0xced所说,也许两者都不应该做,但在iOS上调用exit()永远不是一个好主意;调试时首选abort()。只有在现有tableview中搜索时,此选项才适用。除此之外,这是一个非常好的解决方案,只需很少的代码更改。太棒了,兄弟。竖起大拇指你是如何处理表视图数据源方法的,这样表视图就会知道是否显示“过滤列表”的?下面是我所做的:这里的答案非常有用,但仍然很奇怪。。。对象确实会被过滤,但当我向下滚动表视图时,会出现异常,因为fetchController在特定索引处没有对象。。。有什么不对劲?求你了,帮我解决我的问题。。。当我得到过滤结果时,它们以相同的方式显示在tableView中,当我滚动到行数X时,实际行数小于X。。。我该怎么办。。