UISearchController NSFetchResultsController
UISearchController NSFetchResultsController
我收到此错误:
CoreData: error: Serious application error. An exception was caught
from the delegate of NSFetchedResultsController during a call to
-controllerDidChangeContent:. attempt to delete row 5 from section 0 which only contains 1 rows before the update with userInfo (null) If I
edit first or second not last everything is working.
我有一个 tableview 和 UISearchController,当我从 tableview 触摸行时,它会将我发送到另一个 vc,我可以在其中编辑我的日记。
一切正常,除了当我搜索某些东西时,如果结果是我的 TableView 的最后一个条目,当我尝试编辑和保存时,它会给我上面写的错误。
@implementation PlumbListTableViewController
-(void)viewDidLoad {
[super viewDidLoad];
[self.fetchedResultsController performFetch:nil];
}
-(void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:YES];
self.searchController =[[UISearchController alloc] initWithSearchResultsController:nil];
self.searchController.searchResultsUpdater = self;
self.searchController.dimsBackgroundDuringPresentation = NO;
self.searchController.searchBar.frame = CGRectMake(self.searchController.searchBar.frame.origin.x, self.searchController.searchBar.frame.origin.y, self.searchController.searchBar.frame.size.width, 44.0);
self.tableView.tableHeaderView = self.searchController.searchBar;
self.searchController.searchBar.delegate = self;
self.tabBarController.tabBar.hidden = NO;
[self showTotalSum];
[self.tableView reloadData];
}
-(void)searchBarCancelButtonClicked:(UISearchBar *)searchBar{
[self.tableView reloadData];
}
- (void)searchForText:(NSString *)searchText
{
CoreDataStack *coreDataStack = [CoreDataStack defaultStack];
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"AddEntry"];
fetchRequest.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"date" ascending:NO]];
if (self.searchController.searchBar.text.length == 0) {
NSError *error = nil;
self.filteredList = [coreDataStack.managedObjectContext executeFetchRequest:fetchRequest error:&error];
} else {
if (coreDataStack.managedObjectContext) {
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"titluPlumb contains[c] %@", searchText];
[fetchRequest setPredicate:predicate];
NSError *error = nil;
self.filteredList = [coreDataStack.managedObjectContext executeFetchRequest:fetchRequest error:&error];
}
}
}
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController
{
NSString *searchString = searchController.searchBar.text;
[self searchForText:searchString ];
[self.tableView reloadData];
}
-(void)searchBar:(UISearchBar *)searchBar selectedScopeButtonIndexDidChange:(NSInteger)selectedScope
{
[self updateSearchResultsForSearchController:self.searchController];
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:@"edit"]) {
UITableViewCell *cell = sender;
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
UINavigationController *navigationController = segue.destinationViewController;
PlumbAddViewController *entryViewController = (PlumbAddViewController *)navigationController.topViewController;
if (self.searchController.active) {
entryViewController.entry = [self.filteredList objectAtIndex:indexPath.row];
} else {
entryViewController.entry = [self.fetchedResultsController objectAtIndexPath:indexPath];
}
}
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
if (self.searchController.active)
{
return [self.filteredList count];
}
else
{
id <NSFetchedResultsSectionInfo> sectionInfo = [self.fetchedResultsController sections][section];
return [sectionInfo numberOfObjects];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
ConfigureCellPlumb *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
AddEntry *entry = nil;
if (self.searchController.active){
entry = [self.filteredList objectAtIndex:indexPath.row];
} else {
entry = [self.fetchedResultsController objectAtIndexPath:indexPath];
}
cell.titluView.text = entry.titluPlumb;
cell.descriereView.text = entry.bodyPlumb;
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"MM/dd/yyyy"];
NSDate *date = [NSDate dateWithTimeIntervalSince1970:entry.date];
cell.dataLabel.text = [dateFormatter stringFromDate:date];
if (entry.imageDataPlumb) {
cell.imagineView.image = [UIImage imageWithData:entry.imageDataPlumb];
} else {
cell.imagineView.image = [UIImage imageNamed:@"icn_noimage"];
}
return cell;
}
- (NSFetchRequest *)entryListFetchRequest {
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"AddEntry"];
fetchRequest.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"date" ascending:NO]];
return fetchRequest;
}
- (NSFetchedResultsController *)fetchedResultsController {
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
CoreDataStack *coreDataStack = [CoreDataStack defaultStack];
NSFetchRequest *fetchRequest = [self entryListFetchRequest];
_fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:coreDataStack.managedObjectContext sectionNameKeyPath:@"sectionName" cacheName:nil];
_fetchedResultsController.delegate = self;
return _fetchedResultsController;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
AddEntry *entry = [self.fetchedResultsController objectAtIndexPath:indexPath];
CoreDataStack *coreDataStack = [CoreDataStack defaultStack];
[[coreDataStack managedObjectContext] deleteObject:entry];
[coreDataStack saveContext];
}
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
[self.tableView beginUpdates];
}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
switch (type) {
case NSFetchedResultsChangeInsert:
[self.tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
break;
case NSFetchedResultsChangeUpdate:
[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
break;
case NSFetchedResultsChangeMove:
[self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
[self.tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
break;
}
}
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id<NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {
switch (type) {
case NSFetchedResultsChangeInsert:
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationAutomatic];
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationAutomatic];
break;
case NSFetchedResultsChangeUpdate:
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationAutomatic];
break;
}
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
[self.tableView endUpdates];
}
@end
更新:
- (NSFetchRequest *)entryListFetchRequest {
self.searchFetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"AddEntry"];
self.searchFetchRequest.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"date" ascending:NO]];
return self.searchFetchRequest;
}
- (NSFetchedResultsController *)fetchedResultsController {
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
self.coreDataStack = [CoreDataStack defaultStack];
NSFetchRequest *fetchRequest = [self entryListFetchRequest];
_fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.coreDataStack.managedObjectContext sectionNameKeyPath:@"sectionName" cacheName:nil];
_fetchedResultsController.delegate = self;
if (self.searchController.searchBar.text.length != 0) {
NSString *searchText = self.searchController.searchBar.text;
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"titluPlumb contains[c] %@", searchText];
[self.searchFetchRequest setPredicate:predicate];
NSError *error = nil;
self.filteredList = [self.coreDataStack.managedObjectContext executeFetchRequest:self.searchFetchRequest error:&error];
}
return _fetchedResultsController;
}
更新 2
- (NSFetchedResultsController *)fetchedResultsController {
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
self.coreDataStack = [CoreDataStack defaultStack];
NSFetchRequest *fetchRequest = [self entryListFetchRequest];
if (self.searchController.searchBar.text.length !=0) {
NSString *searchText = self.searchController.searchBar.text;
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"titluPlumb contains[c] %@", searchText];
fetchRequest.predicate = predicate;
}
_fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.coreDataStack.managedObjectContext sectionNameKeyPath:@"sectionName" cacheName:nil];
_fetchedResultsController.delegate = self;
return _fetchedResultsController;
}
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController
{
self.fetchedResultsController = 无;
[self.tableView 重新加载数据];
}
}
更新 3
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
id <NSFetchedResultsSectionInfo> sectionInfo = [self.fetchedResultsController sections][section];
return [sectionInfo numberOfObjects];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
ConfigureCellPlumb *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
AddEntry *entry = nil;
entry = [self.fetchedResultsController objectAtIndexPath:indexPath];
cell.titluView.text = entry.titluPlumb;
cell.descriereView.text = entry.bodyPlumb;
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"MM/dd/yyyy"];
NSDate *date = [NSDate dateWithTimeIntervalSince1970:entry.date];
cell.dataLabel.text = [dateFormatter stringFromDate:date];
if (entry.imageDataPlumb) {
cell.imagineView.image = [UIImage imageWithData:entry.imageDataPlumb];
} else {
cell.imagineView.image = [UIImage imageNamed:@"icn_noimage"];
}
return cell;
}
更新 4
- (NSFetchedResultsController *)fetchedResultsController {
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
self.coreDataStack = [CoreDataStack defaultStack];
self.searchFetchRequest = [self entryListFetchRequest];
if (self.searchController.searchBar.text.length !=0) {
NSString *searchText = self.searchController.searchBar.text;
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"titluPlumb contains[c] %@", searchText];
self.searchFetchRequest.predicate = predicate;
[self.tableView reloadData];
}
_fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:self.searchFetchRequest managedObjectContext:self.coreDataStack.managedObjectContext sectionNameKeyPath:@"sectionName" cacheName:nil];
_fetchedResultsController.delegate = self;
return [_fetchedResultsController fetchedObjects];
}
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController
{
self.fetchedResultsController = nil;
[self.tableView reloadData];
NSLog(@"%@", self.searchFetchRequest.predicate);
}
问题是您的 table 视图同时由 2 个源驱动(在这种情况下),因为您在搜索时没有完全关闭 FRC。因此,您进行搜索并进行编辑,FRC 会看到这一点并尝试更新 table,但是 - table 当前未显示 FRC 行 - 因此有时它会失败。
要么使用 FRC 通过更改获取请求的谓词来进行搜索,要么在搜索时销毁 FRC,并在完成后重新创建它。
因此,将您的 FRC 方法更改为:
- (NSFetchedResultsController *)fetchedResultsController {
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
self.coreDataStack = [CoreDataStack defaultStack];
NSFetchRequest *fetchRequest = [self entryListFetchRequest];
if (self.searchController.searchBar.text.length != 0) {
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"titluPlumb contains[c] %@", searchText];
fetchRequest.predicate = predicate;
}
_fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.coreDataStack.managedObjectContext sectionNameKeyPath:@"sectionName" cacheName:nil];
_fetchedResultsController.delegate = self;
return _fetchedResultsController;
}
每当您开始搜索/更改搜索文本/结束搜索时,请执行以下操作:
self.fetchedResultsController = nil;
[self.tableView reloadData];
我收到此错误:
CoreData: error: Serious application error. An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:. attempt to delete row 5 from section 0 which only contains 1 rows before the update with userInfo (null) If I edit first or second not last everything is working.
我有一个 tableview 和 UISearchController,当我从 tableview 触摸行时,它会将我发送到另一个 vc,我可以在其中编辑我的日记。 一切正常,除了当我搜索某些东西时,如果结果是我的 TableView 的最后一个条目,当我尝试编辑和保存时,它会给我上面写的错误。
@implementation PlumbListTableViewController
-(void)viewDidLoad {
[super viewDidLoad];
[self.fetchedResultsController performFetch:nil];
}
-(void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:YES];
self.searchController =[[UISearchController alloc] initWithSearchResultsController:nil];
self.searchController.searchResultsUpdater = self;
self.searchController.dimsBackgroundDuringPresentation = NO;
self.searchController.searchBar.frame = CGRectMake(self.searchController.searchBar.frame.origin.x, self.searchController.searchBar.frame.origin.y, self.searchController.searchBar.frame.size.width, 44.0);
self.tableView.tableHeaderView = self.searchController.searchBar;
self.searchController.searchBar.delegate = self;
self.tabBarController.tabBar.hidden = NO;
[self showTotalSum];
[self.tableView reloadData];
}
-(void)searchBarCancelButtonClicked:(UISearchBar *)searchBar{
[self.tableView reloadData];
}
- (void)searchForText:(NSString *)searchText
{
CoreDataStack *coreDataStack = [CoreDataStack defaultStack];
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"AddEntry"];
fetchRequest.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"date" ascending:NO]];
if (self.searchController.searchBar.text.length == 0) {
NSError *error = nil;
self.filteredList = [coreDataStack.managedObjectContext executeFetchRequest:fetchRequest error:&error];
} else {
if (coreDataStack.managedObjectContext) {
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"titluPlumb contains[c] %@", searchText];
[fetchRequest setPredicate:predicate];
NSError *error = nil;
self.filteredList = [coreDataStack.managedObjectContext executeFetchRequest:fetchRequest error:&error];
}
}
}
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController
{
NSString *searchString = searchController.searchBar.text;
[self searchForText:searchString ];
[self.tableView reloadData];
}
-(void)searchBar:(UISearchBar *)searchBar selectedScopeButtonIndexDidChange:(NSInteger)selectedScope
{
[self updateSearchResultsForSearchController:self.searchController];
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:@"edit"]) {
UITableViewCell *cell = sender;
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
UINavigationController *navigationController = segue.destinationViewController;
PlumbAddViewController *entryViewController = (PlumbAddViewController *)navigationController.topViewController;
if (self.searchController.active) {
entryViewController.entry = [self.filteredList objectAtIndex:indexPath.row];
} else {
entryViewController.entry = [self.fetchedResultsController objectAtIndexPath:indexPath];
}
}
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
if (self.searchController.active)
{
return [self.filteredList count];
}
else
{
id <NSFetchedResultsSectionInfo> sectionInfo = [self.fetchedResultsController sections][section];
return [sectionInfo numberOfObjects];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
ConfigureCellPlumb *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
AddEntry *entry = nil;
if (self.searchController.active){
entry = [self.filteredList objectAtIndex:indexPath.row];
} else {
entry = [self.fetchedResultsController objectAtIndexPath:indexPath];
}
cell.titluView.text = entry.titluPlumb;
cell.descriereView.text = entry.bodyPlumb;
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"MM/dd/yyyy"];
NSDate *date = [NSDate dateWithTimeIntervalSince1970:entry.date];
cell.dataLabel.text = [dateFormatter stringFromDate:date];
if (entry.imageDataPlumb) {
cell.imagineView.image = [UIImage imageWithData:entry.imageDataPlumb];
} else {
cell.imagineView.image = [UIImage imageNamed:@"icn_noimage"];
}
return cell;
}
- (NSFetchRequest *)entryListFetchRequest {
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"AddEntry"];
fetchRequest.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"date" ascending:NO]];
return fetchRequest;
}
- (NSFetchedResultsController *)fetchedResultsController {
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
CoreDataStack *coreDataStack = [CoreDataStack defaultStack];
NSFetchRequest *fetchRequest = [self entryListFetchRequest];
_fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:coreDataStack.managedObjectContext sectionNameKeyPath:@"sectionName" cacheName:nil];
_fetchedResultsController.delegate = self;
return _fetchedResultsController;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
AddEntry *entry = [self.fetchedResultsController objectAtIndexPath:indexPath];
CoreDataStack *coreDataStack = [CoreDataStack defaultStack];
[[coreDataStack managedObjectContext] deleteObject:entry];
[coreDataStack saveContext];
}
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
[self.tableView beginUpdates];
}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
switch (type) {
case NSFetchedResultsChangeInsert:
[self.tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
break;
case NSFetchedResultsChangeUpdate:
[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
break;
case NSFetchedResultsChangeMove:
[self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
[self.tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
break;
}
}
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id<NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {
switch (type) {
case NSFetchedResultsChangeInsert:
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationAutomatic];
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationAutomatic];
break;
case NSFetchedResultsChangeUpdate:
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationAutomatic];
break;
}
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
[self.tableView endUpdates];
}
@end
更新:
- (NSFetchRequest *)entryListFetchRequest {
self.searchFetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"AddEntry"];
self.searchFetchRequest.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"date" ascending:NO]];
return self.searchFetchRequest;
}
- (NSFetchedResultsController *)fetchedResultsController {
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
self.coreDataStack = [CoreDataStack defaultStack];
NSFetchRequest *fetchRequest = [self entryListFetchRequest];
_fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.coreDataStack.managedObjectContext sectionNameKeyPath:@"sectionName" cacheName:nil];
_fetchedResultsController.delegate = self;
if (self.searchController.searchBar.text.length != 0) {
NSString *searchText = self.searchController.searchBar.text;
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"titluPlumb contains[c] %@", searchText];
[self.searchFetchRequest setPredicate:predicate];
NSError *error = nil;
self.filteredList = [self.coreDataStack.managedObjectContext executeFetchRequest:self.searchFetchRequest error:&error];
}
return _fetchedResultsController;
}
更新 2
- (NSFetchedResultsController *)fetchedResultsController {
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
self.coreDataStack = [CoreDataStack defaultStack];
NSFetchRequest *fetchRequest = [self entryListFetchRequest];
if (self.searchController.searchBar.text.length !=0) {
NSString *searchText = self.searchController.searchBar.text;
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"titluPlumb contains[c] %@", searchText];
fetchRequest.predicate = predicate;
}
_fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.coreDataStack.managedObjectContext sectionNameKeyPath:@"sectionName" cacheName:nil];
_fetchedResultsController.delegate = self;
return _fetchedResultsController;
}
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController
{
self.fetchedResultsController = 无; [self.tableView 重新加载数据];
}
}
更新 3
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
id <NSFetchedResultsSectionInfo> sectionInfo = [self.fetchedResultsController sections][section];
return [sectionInfo numberOfObjects];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
ConfigureCellPlumb *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
AddEntry *entry = nil;
entry = [self.fetchedResultsController objectAtIndexPath:indexPath];
cell.titluView.text = entry.titluPlumb;
cell.descriereView.text = entry.bodyPlumb;
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"MM/dd/yyyy"];
NSDate *date = [NSDate dateWithTimeIntervalSince1970:entry.date];
cell.dataLabel.text = [dateFormatter stringFromDate:date];
if (entry.imageDataPlumb) {
cell.imagineView.image = [UIImage imageWithData:entry.imageDataPlumb];
} else {
cell.imagineView.image = [UIImage imageNamed:@"icn_noimage"];
}
return cell;
}
更新 4
- (NSFetchedResultsController *)fetchedResultsController {
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
self.coreDataStack = [CoreDataStack defaultStack];
self.searchFetchRequest = [self entryListFetchRequest];
if (self.searchController.searchBar.text.length !=0) {
NSString *searchText = self.searchController.searchBar.text;
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"titluPlumb contains[c] %@", searchText];
self.searchFetchRequest.predicate = predicate;
[self.tableView reloadData];
}
_fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:self.searchFetchRequest managedObjectContext:self.coreDataStack.managedObjectContext sectionNameKeyPath:@"sectionName" cacheName:nil];
_fetchedResultsController.delegate = self;
return [_fetchedResultsController fetchedObjects];
}
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController
{
self.fetchedResultsController = nil;
[self.tableView reloadData];
NSLog(@"%@", self.searchFetchRequest.predicate);
}
问题是您的 table 视图同时由 2 个源驱动(在这种情况下),因为您在搜索时没有完全关闭 FRC。因此,您进行搜索并进行编辑,FRC 会看到这一点并尝试更新 table,但是 - table 当前未显示 FRC 行 - 因此有时它会失败。
要么使用 FRC 通过更改获取请求的谓词来进行搜索,要么在搜索时销毁 FRC,并在完成后重新创建它。
因此,将您的 FRC 方法更改为:
- (NSFetchedResultsController *)fetchedResultsController {
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
self.coreDataStack = [CoreDataStack defaultStack];
NSFetchRequest *fetchRequest = [self entryListFetchRequest];
if (self.searchController.searchBar.text.length != 0) {
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"titluPlumb contains[c] %@", searchText];
fetchRequest.predicate = predicate;
}
_fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.coreDataStack.managedObjectContext sectionNameKeyPath:@"sectionName" cacheName:nil];
_fetchedResultsController.delegate = self;
return _fetchedResultsController;
}
每当您开始搜索/更改搜索文本/结束搜索时,请执行以下操作:
self.fetchedResultsController = nil;
[self.tableView reloadData];