为啥 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,为啥它受到保护?