再次执行提取后是否重新加载了表视图?
这对我很有用:
self.fetchedResultsController = nil;
NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error]) {
NSLog(@"Error in refetch: %@",[error localizedDescription]);
abort();
}
[self.tableView reloadData];
更新
获取的结果控制器正在观察对象的变化,而不是域对象。由于我们正在更改域对象上的帐户,所以获取的结果控制器没有更新(除了新的内容)是有意义的。
理想的解决方案是告诉托管对象上下文或获取的结果控制器哪些确切的事情已经“改变”(循环处理以前拥有帐户的域中的事情),但这仍然是一个手动过程。
另一种方法是再次执行FETCH并重新加载为我工作的表。
我根据你的描述创建了这个模型:
帐户---域---事情
为了测试这一点,我在域1中创建了“1”和“2”,在域2中创建了“3”、“4”和“5”。域一拥有帐户,而域二没有帐户。
当应用程序加载时,表视图按预期显示“1”和“2”。
当我点击“更改”时,域2被分配帐户,域1失去其帐户。另外,在域2中创建了一个名为“six”的新东西。
“6”和“1”和“2”一起出现,即使它们不再满足谓词。这与您描述的问题相匹配。
然后,我点击“refetch”,表格会重新加载“3”、“4”、“5”和“6”。这是所期望的行为。
以下是相关的视图控制器代码:
- (void)addTestData {
account = [NSEntityDescription insertNewObjectForEntityForName:@"Account" inManagedObjectContext:self.managedObjectContext];
domainOne = [NSEntityDescription insertNewObjectForEntityForName:@"Domain" inManagedObjectContext:self.managedObjectContext];
domainTwo = [NSEntityDescription insertNewObjectForEntityForName:@"Domain" inManagedObjectContext:self.managedObjectContext];
[domainOne setValue:account forKey:@"domainCurrentAccount"];
NSArray *thingNames = [NSArray arrayWithObjects:@"One", @"Two", @"Three", @"Four", @"Five", nil];
for (NSString *name in thingNames) {
NSManagedObject *thing = [NSEntityDescription insertNewObjectForEntityForName:@"Thing" inManagedObjectContext:self.managedObjectContext];
[thing setValue:name forKey:@"thingName"];
if (name == @"One" || name == @"Two") {
[thing setValue:domainOne forKey:@"thingDomain"];
} else {
[thing setValue:domainTwo forKey:@"thingDomain"];
}
}
}
- (void)change {
[domainTwo setValue:account forKey:@"domainCurrentAccount"];
[domainOne setValue:nil forKey:@"domainCurrentAccount"];
NSManagedObject *thing = [NSEntityDescription insertNewObjectForEntityForName:@"Thing" inManagedObjectContext:self.managedObjectContext];
[thing setValue:@"Six" forKey:@"thingName"];
[thing setValue:domainTwo forKey:@"thingDomain"];
}
- (void)refetch {
self.fetchedResultsController = nil;
NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error]) {
NSLog(@"Error in refetch: %@",[error localizedDescription]);
abort();
}
[self.tableView reloadData];
}
- (void)viewDidLoad {
[super viewDidLoad];
UIBarButtonItem *changeButton = [[UIBarButtonItem alloc] initWithTitle:@"Change" style:UIBarButtonItemStyleBordered target:self action:@selector(change)];
self.navigationItem.leftBarButtonItem = changeButton;
[changeButton release];
UIBarButtonItem *refetchButton = [[UIBarButtonItem alloc] initWithTitle:@"Refetch" style:UIBarButtonItemStyleBordered target:self action:@selector(refetch)];
self.navigationItem.rightBarButtonItem = refetchButton;
[refetchButton release];
[self addTestData];
NSError *error = nil;
if (![[self fetchedResultsController] performFetch:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}