代码之家  ›  专栏  ›  技术社区  ›  burki

如何使用nsfetchedresultsController和uiSearchDisplayController

  •  14
  • burki  · 技术社区  · 15 年前

    我一直在用核心数据创建一个iPhone应用程序。

    首先,使用nsfetchedResultsController和uiSearchDisplayController一起获取结果是否有意义?你能推荐别的吗?

    我已经尝试将nsfetchedResultController和uiSearchDisplayController组合了很长时间。我一直在考虑在 (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption 方法转换为uiviewController的nsFetchedResultController。但这不太管用。

    那么,你知道如何为我的问题实现一个解决方案吗?感谢您已经发布了答案或指向优秀教程的链接。

    编辑

    这是我的密码。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;
    } 
    
    3 回复  |  直到 14 年前
        1
  •  21
  •   IdleGod    14 年前

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

    假设您启动了如下获取的结果控制器。注意cachename属性。

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

    更改谓词时,只需添加:

     [NSFetchedResultsController deleteCacheWithName:@"UserSearch"];
    

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

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

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

        2
  •  7
  •   psuedonick    14 年前

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

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

    —— NSFetchedResultsController

    (我会评论idle的回答,但我没有因果报应。)

        3
  •  1
  •   gerry3    15 年前

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

    通常,使用获取的结果控制器来帮助实现表视图数据源和委托方法。此外,还可以为提取的结果控制器创建和使用提取请求。这是所有的样板(在选择了“使用核心数据进行存储”选项的情况下创建新项目时,请参见Apple提供的模板代码)。

    它在fetch请求中,您可以创建和指定谓词。这将允许您筛选表显示的对象。例如:

    // only fetch objects with myAttribute set to someValue
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"myAttribute == %@",someValue];
    [fetchRequest setPredicate:pred];