为啥 searchFetchedResultsController 设置为零?

Posted

技术标签:

【中文标题】为啥 searchFetchedResultsController 设置为零?【英文标题】:Why searchFetchedResultsController set to nil?为什么 searchFetchedResultsController 设置为零? 【发布时间】:2012-09-23 10:27:08 【问题描述】:

以下代码来自this post 的已接受答案,关于使用 Core Data 在表格视图中实现搜索栏。它使用两个获取结果控制器(FRC)。一种用于“普通”表视图,一种用于搜索结果表视图。它使用辅助方法来决定表视图数据源方法、FRC 委托方法等使用哪个 FRC。

除以下部分外,我了解大部分代码。我应该输入什么代码来替换 cmets "update the filter..."?为什么我应该将 self.searchFetchedResultsController 及其委托设置为 nil?

- (void)filterContentForSearchText:(NSString*)searchText scope:(NSInteger)scope

    // update the filter, in this case just blow away the FRC and let lazy evaluation create another with the relevant search info
    self.searchFetchedResultsController.delegate = nil;
    self.searchFetchedResultsController = nil;
    ...

【问题讨论】:

【参考方案1】:

当您将 fetchedResultsController 设置为 nil 时会发生以下情况。下次表视图(或搜索结果表视图)需要数据时,它将查询其datasource,而后者又引用(不存在的)FRC。如果您查看 fetchedResultsController 方法,您会发现 FRC 是延迟创建的 - 仅当它是 nil 时。在初始化例程中,获取请求被执行并且新的结果被提供给数据源。

虽然这很可靠,但有理由认为没有完全破坏 FRC。它是冗余的,需要更多的时间、CPU 和电池电量。只需调用即可达到完全相同的效果

[fetchedResultsController performFetch:nil]; 

现在数据源也将拥有最新的可用数据。

编辑

如 cmets 中所述,您应该真正修改 fetchedResultsController 方法以延迟创建。查看 Apple 模板以获取指导。

if (_fetchedResultsController != nil) 
   return _fetchedResultsController;

// continue creating a new one

【讨论】:

“如果您查看 fetchedResultsController 方法”.. 您能否更具体地说明究竟是哪种方法?是- (NSFetchedResultsController *)newFetchedResultsControllerWithSearch:(NSString *)searchString 吗? 我仍然无法理解“FRC 是惰性创建的——仅当它为 nil 时”的代码的哪一部分。你能把那部分复制粘贴到这里吗? “FRC 创建代码”在您发布的链接中。如果没有 FRC self.fetchedResultsController 将创建一个新的。您将在该方法中找到正确的提取。看来情况比我想象的还要糟糕!此方法将每次重新创建 FRC。这是一个非常不理想的模式。 我同意。我只是在另一篇文章中写了一个解决方案。 ***.com/questions/12555208/…【参考方案2】:

我简要阅读了已接受答案的代码。很多只是骨架,显示了要实现的方法。也就是说,我从未在filterContentForSearchText:scope: 方法中实现“吹走FRC”的方法;但我确实有 NSFetchedResultsController 支持的表格视图,在生产代码中具有搜索栏功能。

以下是其中之一的filterContentForSearchText:scope 示例:

- (void)filterContentForSearchText:(NSString *)searchText scope:(NSString *)scope;

    /*  clear the filtered list */
    [_mutableFilteredLadders removeAllObjects];

    /*  in background queue filter our list */
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
        NSPredicate *ladderTitlePredicate = [NSPredicate predicateWithFormat:@"title CONTAINS[cd] %@",searchText];
        NSPredicate *ladderTextPredicate = [NSPredicate predicateWithFormat:@"ANY ladderItems.text CONTAINS[cd] %@",searchText];
        NSPredicate *searchPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:ARRAY(ladderTextPredicate,ladderTitlePredicate)];

        [_mutableFilteredLadders addObjectsFromArray:[[self allLadders] filteredArrayUsingPredicate:searchPredicate]];

        /* reload table on the main queue */
        dispatch_async(dispatch_get_main_queue(), ^
            [[[self searchDisplayController] searchResultsTableView] reloadData];
        );
    );

【讨论】:

感谢您实施过滤方法。在后台队列中进行过滤可能会增强用户体验。但是,您使用 NSArray 来存储搜索结果(可能还有另一个数组来存储所有获取的对象)。这不是我在帖子中需要的数据结构。

以上是关于为啥 searchFetchedResultsController 设置为零?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 DataGridView 上的 DoubleBuffered 属性默认为 false,为啥它受到保护?

为啥需要softmax函数?为啥不简单归一化?

为啥 g++ 需要 libstdc++.a?为啥不是默认值?

为啥或为啥不在 C++ 中使用 memset? [关闭]

为啥临时变量需要更改数组元素以及为啥需要在最后取消设置?

为啥 CAP 定理中的 RDBMS 分区不能容忍,为啥它可用?