【发布时间】:2012-09-15 05:53:10
【问题描述】:
我是 iOS 编程的新手。 我已经使用 NSFetchedResultsController 实现了一个使用 CoreData 填充的 UITableView。这部分工作得很好。然后我添加了一个 UISearchDisplayController 来搜索表格。搜索本身工作正常,但似乎我在重新加载视图时泄漏了我的 CoreData 对象。应用程序不会崩溃,但 Instrument 会在我每次执行搜索或关闭 SearchView 时报告 CoreData 框架中的对象泄漏。
我已经实现了这样的搜索功能:
- (void)filterContentForSearchText:(NSString*)searchText
scope:(NSString*)scope
{
if (searchText && searchText.length) {
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name contains %@", searchText];
[self.fetchedResultsController.fetchRequest setPredicate:predicate];
}
NSError *error = nil;
if (![[self fetchedResultsController] performFetch:&error]) {
// Handle error
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
exit(-1); // Fail
}
}
当我关闭 SearchBar 时:
- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar
{
NSLog(@"searchBarTextDidEndEditing: Reset fetchedResultsController predicate" );
self.fetchedResultsController.fetchRequest.predicate = nil;
NSError *error = nil;
if (![[self fetchedResultsController] performFetch:&error]) {
NSLog(@"Unresolved error %@, %@",error,[error userInfo]);
abort();
}
}
谁能看出我做错了什么?
谢谢 凸轮
更新:我关注了这篇文章 How to filter NSFetchedResultsController (CoreData) with UISearchDisplayController/UISearchBar 并以相同的方式实现了 getter,但是当我在搜索栏中“键入”一些字母时,我仍然会泄漏核心数据对象,所以问题似乎是当我获取新的数据不会关闭视图。
代码如下:
1) 当我在搜索栏中输入时,我设置为 nil self.searchBarFetchedResultsController
(void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
self.searchBarFetchedResultsController.delegate = nil;
self.searchBarFetchedResultsController = nil;
}
2) 当再次调用 getter 时,我按照示例分配一个新的 FRC。
- (NSFetchedResultsController *)searchBarFetchedResultsController
{
if (_searchBarFetchedResultsController != nil)
{
return _searchBarFetchedResultsController;
}
_searchBarFetchedResultsController = [self newFetchedResultsControllerWithSearch:self.searchDisplayController.searchBar.text];
return _searchBarFetchedResultsController;
}
- (NSFetchedResultsController *)newFetchedResultsControllerWithSearch:(NSString *)searchString
{
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Beers"];
request.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)]];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name contains %@", searchString];
if(searchString.length)
{
[request setPredicate:predicate];
}
[request setFetchBatchSize:20];
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request
managedObjectContext:self.beerDB2.managedObjectContext
sectionNameKeyPath:nil
cacheName:nil];
aFetchedResultsController.delegate = self;
NSError *error = nil;
if (![aFetchedResultsController performFetch:&error])
}
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
return aFetchedResultsController;
}
然后,当我从代表方法访问 FRC 时,我正在使用此方法来获取正确的方法。
- (NSFetchedResultsController *)fetchedResultsControllerForTableView:(UITableView *)tableView
{
return tableView == self.favTab ? self.fetchedResultsController : self.searchBarFetchedResultsController;
}
除了 Inspector 告诉我我泄露了数百个核心数据对象之外,一切都运行良好 :( 让我抓狂的是,我并非一直在泄露它们。对于某些搜索会正常工作,然后它会开始泄露。届时任何后续搜索都会触发泄漏。
【问题讨论】:
-
你有用于 fetchedResultsController 的自定义 getter 吗?如果是这样,那段代码是什么样的?
-
嗨 Hunter,我想我对这个问题有一个初步的想法。我为两个 TableView 使用一个 FRC。一开始我不明白它们是分开的(最初的和用于搜索栏的)。今晚我将尝试用两个 FRC 来实现它,看看它是否有效。如果没有,我会发布更多细节!谢谢!
标签: ios uitableview core-data uisearchdisplaycontroller