14

我一直在使用 Core Data 创建一个 iPhone 应用程序。

首先,同时使用 NSFetchedResultsController 和 UISearchDisplayController 来获取结果有意义吗?你会推荐别的东西吗?

我一直在尝试将 NSFetchedResultController 和 UISearchDisplayController 结合起来。我一直在考虑(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption在 UIViewController 的 NSFetchedResultController 的方法中设置一个 NSPredicate。但这不是很好。

那么,您知道如何为我的问题实施解决方案吗?感谢您发布优秀教程的答案或链接。

编辑

这是我的代码。UISearchDisplayDelegate 方法调用(void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope应该在 NSFetchedResultController 中设置谓词的方法。我还添加了 NSFetchedResultController 的代码。

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
    [self filterContentForSearchText:searchString scope:
     [[self.searchDisplayController.searchBar scopeButtonTitles] objectAtIndex:[self.searchDisplayController.searchBar selectedScopeButtonIndex]]];

    // Return YES to cause the search result table view to be reloaded.
    return YES;
}


- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption
{
    [self filterContentForSearchText:[self.searchDisplayController.searchBar text] scope:
     [[self.searchDisplayController.searchBar scopeButtonTitles] objectAtIndex:searchOption]];

    // Return YES to cause the search result table view to be reloaded.
    return YES;
}


- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
    NSString *query = self.searchDisplayController.searchBar.text;
    if (query && query.length) {
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"Name contains[cd] %@", query];
        [fetchedResultsController.fetchRequest setPredicate:predicate];
    }

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

}


- (NSFetchedResultsController *)fetchedResultsController {

    if (fetchedResultsController != nil) {
        return fetchedResultsController;
    }

    /*
     Set up the fetched results controller.
    */
    // Create the fetch request for the entity.
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    // Edit the entity name as appropriate.
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:managedObjectContext];
    [fetchRequest setEntity:entity];

    // Set the batch size to a suitable number.
    [fetchRequest setFetchBatchSize:20];

    // Edit the sort key as appropriate.
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"timeStamp" ascending:NO];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];

    [fetchRequest setSortDescriptors:sortDescriptors];

    // Edit the section name key path and cache name if appropriate.
    // nil for section name key path means "no sections".
    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:@"Root"];
    aFetchedResultsController.delegate = self;
    self.fetchedResultsController = aFetchedResultsController;

    [aFetchedResultsController release];
    [fetchRequest release];
    [sortDescriptor release];
    [sortDescriptors release];

    return fetchedResultsController;
} 
4

3 回答 3

21

看看你的代码,它就在那里。我在使用这种方法更改搜索时遇到了问题。解决方法:清除缓存!

假设您按如下方式启动了获取的结果控制器。请注意 cacheName 属性。

    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:[self fetchRequest] managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:@"UserSearch"];

当您更改谓词时,只需添加:

 [NSFetchedResultsController deleteCacheWithName:@"UserSearch"];

就像魔术一样,它会很好地工作。

您还需要监视搜索显示控制器何时结束其搜索,并擦除您的谓词。

虽然这个线程看起来已经死了,但我在谷歌上找到了它,所以也许有人会使用它。:)

于 2010-03-04T19:29:35.167 回答
7

根据文档,您要么希望使用谓词将结果过滤到数组中,要么重新初始化 fetchedResultsController。

重要提示:初始化控制器后,您不得修改获取请求。例如,您不得更改谓词或排序顺序。

-- NSFetchedResultsController

(我会评论空闲的答案,但我没有业力。)

于 2010-07-13T20:12:30.827 回答
1

听起来您只是对获取和显示对象感兴趣。在这种情况下,您不使用搜索显示控制器。搜索显示控制器与搜索栏一起使用,以帮助允许用户输入文本搜索您的内容。

通常,您使用获取的结果控制器来帮助您实现表视图数据源和委托方法。此外,您为获取的结果控制器创建和使用获取请求。这都是样板文件(当您创建一个新项目并选择“使用核心数据进行存储”选项时,请参阅 Apple 提供的模板代码)。

您可以在获取请求中创建和指定谓词。这将允许您过滤表格显示的对象。例如:

// only fetch objects with myAttribute set to someValue
NSPredicate *pred = [NSPredicate predicateWithFormat:@"myAttribute == %@",someValue];
[fetchRequest setPredicate:pred];
于 2010-02-03T18:47:45.627 回答