我已经解决这个问题几个小时了,到目前为止没有成功。我在这里阅读了所有可能与我的问题有关的问题。
我有两个实体(A,B),它们通过像这样的一对多关系以树状结构相互连接:A <--->> B。
有一个由 NSFetchedResultsController 支持的 UITableViewController 来显示与实体 A 的选定对象相关的实体 B 的所有对象。我为此使用谓词:
- (NSFetchedResultsController *)fetchedResultsController
{
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"B" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
[fetchRequest setFetchBatchSize:20];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"controlDate" ascending:NO];
NSArray *sortDescriptors = @[sortDescriptor];
[fetchRequest setSortDescriptors:sortDescriptors];
NSMutableArray *subpredicates = [NSMutableArray array];
NSPredicate *predicate1 = [NSPredicate predicateWithFormat:@"isRelatedTo = %@", selectedObjectOfA];
[subpredicates addObject:predicate1];
NSPredicate *predicate2 = [NSPredicate predicateWithFormat:@"syncStatus != %d", ObjectDeleted];
[subpredicates addObject:predicate2];
NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:subpredicates];
[fetchRequest setPredicate:predicate];
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;
NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
return _fetchedResultsController;
}
一切都适用于添加、删除和编辑对象。该表会相应更新。我的类符合 NSFetchedResultsControllerDelegate 并且委托方法是样板文件。
但我希望用户能够通过点击“向上”/“向下”按钮来循环浏览实体 A 的所有对象,而无需返回导航堆栈(就像可以直接在邮件应用程序中循环浏览电子邮件一样)。B 的相关对象的数量取决于 A 的选定对象(在无和 20 之间)。
问题来了:我的意图是通过更改谓词来刷新 FRC 的结果(不是它的结构或语法,而只是 'selectedObjectOfA' 的值并调用
[self.fetchedResultsController performFetch:&error];
其余的应由 FRC 完成。
第一个问题是:这种方法正确吗?
以下是我已经尝试过的场景:
只需将“selectedObjectOfA”设置为一个新值并调用 performFetch 总是显示相同的结果(因为我想 fetchRequest 和谓词没有被更新)
像这样“重置” FRC 的 fetchrequest
NSMutableArray *subprediactes = [NSMutableArray array]; NSPredicate *predicate1 = [NSPredicate predicateWithFormat:@"isRelatedTo = %@", self.selectedObjectOfA]; [subprediactes addObject:predicate1]; NSPredicate *predicate2 = [NSPredicate predicateWithFormat:@"syncStatus != %d", ObjectDeleted]; [subprediactes addObject:predicate2]; NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:subprediactes]; [self.fetchedResultsController.fetchRequest setPredicate:predicate];
更新 FRC 并返回正确的数据,但应用程序因行数不正确而崩溃
'Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (1) must be equal to the number of rows contained in that section before the update (5), plus or minus the number of rows inserted or deleted from that section (0 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'
因为没有调用 NSFetchedResultsController 委托方法。因此 tableView 中的行数不会适应新结果(根据错误消息返回的对象数是正确的)。
第二个问题是:为什么委托在添加/删除对象时触发,而不是在谓词(以及结果)改变之后?
先感谢您。