您是否在重新執行提取操作後重新加載表格視圖?
這爲我工作:
self.fetchedResultsController = nil;
NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error]) {
NSLog(@"Error in refetch: %@",[error localizedDescription]);
abort();
}
[self.tableView reloadData];
UPDATE
獲取的成果控制器觀察事物對象的變化,而不是域對象。由於我們正在更改域對象上的帳戶,因此獲取的結果控制器不會更新(新的Thing除外)。
理想的解決方案是告訴託管對象上下文或獲取結果控制器哪些確切的事情已經「改變」(先前擁有該賬戶的域中的事物上的循環)的方式,但這仍然是手動過程。
另一種方法是再次執行提取並重新載入適用於我的表格。
我創建根據您的描述這個模型:
帳戶< --->域名< --- >>東西
爲了測試這一點,我創造的事「一」和「二」中域domainOne和事物「三」,「四」和「五」域域二。 domainOne擁有賬戶,而domainTwo沒有賬戶。
當應用程序加載時,表視圖按預期顯示事物「一」和「兩」。
當我點擊「更改」時,domainTwo被分配帳戶,並且domainOne丟失其帳戶。此外,在domainTwo中創建了一個名爲「Six」的新事物。
即使他們不再符合謂詞,「Six」與「One」和「Two」一起出現。這與您描述的問題相符。
然後,我點擊「Refetch」,表格會重新加載「Three」,「Four」,「Five」和「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();
}
}
我試過,沒有效果。不管怎麼樣,因爲獲取的結果控制器正在關注MOC上的所有更改,並且所有其他表都更新了它需要的集合,所以它不應該是必需的。重新加載桌面視圖是最後的手段,因爲它不是動畫並殺死任何正在進行的動畫。 – 2009-11-21 15:42:09
我解釋了爲什麼這不是我們最初預期的方式,並增加了我的原始解決方案的細節。 – gerry3 2009-11-21 20:08:42
有趣,但是你的代碼有一個關鍵的區別:在重新讀取你扔掉當前提取的結果控制器並創建一個新的。我具體詢問使用相同的控制器並要求它執行另一次獲取,因此,我假設,使其重新評估所有實體與謂詞。 這可能是什麼都不做,但文檔沒有說。提取可能是一次性事件,一旦有結果,不會再提取。沒有「取消」來拋棄它所具有的結果。 – 2009-11-21 20:37:54