我对 iOS 编程很陌生。我已经使用 NSFetchedResultsController 实现了一个使用 CoreData 填充的 UITableView。这部分工作得很好。然后我添加了一个 UISearchDisplayController 来搜索表格。搜索本身工作正常,但似乎我在重新加载视图时泄漏了我的 CoreData 对象。应用程序不会崩溃,但每次我执行搜索或关闭 SearchView 时,Instrument 都会报告对象在 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 告诉我我正在泄漏数百个核心数据对象之外,所有工作都完美无缺任何后续搜索都会触发泄漏。