2

我有一个获取的结果控制器,我的事物实体上有一个谓词,如下所示:“thingDomain.domainCurrentAccount!=NULL”。它会找到我在当前域中的所有 Thing 对象。当前域由 Account 实体和 Domain 实体之一之间的一对一关系定义。每个事物都属于一个领域,每个领域都有很多事物。除一个以外的所有域都与帐户具有 NULL 关系。

这行得通,我的 tableview 很高兴。

后来我通过修改与Account的关系来更改当前域。我将更多事物添加到现在是当前域的域中,它们被添加到表视图中,因为它们满足谓词。然而,属于现在非当前域的事物仍保留在 tableview 中,即使它们不再满足谓词。

我尝试重新获取,但这没有任何效果,所以我对再次获取实际上做了什么感到困惑。它是否针对实体重新评估谓词?

我通过在更改当前域之前删除当前域中的所有事物来解决问题,但觉得我不应该这样做。

4

1 回答 1

4

再次执行获取后是否重新加载了表视图?

这对我有用:

self.fetchedResultsController = nil;
NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error]) {
    NSLog(@"Error in refetch: %@",[error localizedDescription]);
    abort();
}

[self.tableView reloadData];

UPDATE
获取的结果控制器正在观察事物对象的变化,而不是域对象。由于我们正在更改域对象上的帐户,因此获取的结果控制器没有更新是有道理的(新事物除外)。
理想的解决方案是告诉托管对象上下文或获取的结果控制器哪些确切的事物已经“改变”(循环在域中先前拥有帐户的事物上),但这仍然是一个手动过程。
另一种方法是再次执行提取并重新加载对我有用的表。

我根据您的描述创建了这个模型:

帐号 <---> 域 <--->> 东西

为了测试这一点,我在域域一中创建了事物“一”和“二”,在域域二中创建了事物“三”、“四”和“五”。domainOne 有帐户,而 domainTwo 没有帐户。
当应用程序加载时,表格视图按预期显示事物“一”和“二”。
当我点击“更改”时,为 domainTwo 分配了帐户,并且 domainOne 失去了其帐户。此外,在 domainTwo 中创建了一个名为“Six”的新事物。
事物“六”与“一”和“二”一起出现,即使它们不再满足谓词。这与您描述的问题相符。
然后,我点击“重新获取”,表格重新加载“三”、“四”、“五”和“六”。

这是相关的视图控制器代码:

- (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();
    }
}
于 2009-11-21T10:24:06.630 回答