私のひどい英語を申し訳ありません。 私のiOSアプリに大きな問題があります。アプリケーションにはCore Dataによって管理される大きなデータベースがあります。そして、私はこのデータを表示するための多くのTableViewコントローラを持っています。データベースの変更はすべて、tableviewに表示する必要があります。これは、NSFetchedResultsControllerデリゲートプロトコルを実装することで実現できます。すべての実現は本のように非常に簡単です。アプリケーションは、シミュレータは初めてで始まり、私はデリゲートメソッドが正常に発射されている隣のいくつかのテーブルに新しいエントリを追加した場合:ストップデバッグ後NSFetchedResultsControllerデリゲートは最初のアプリの起動時にのみメソッドを起動します
– controllerWillChangeContent:
– controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:
– controllerDidChangeContent:
をし、アプリケーションを起動し、再び記載されている方法のいずれもが解雇されていません。 [managedObjectContext save]
操作が実行された後でのみ呼び出されます。
これはなぜ起こりますか?
ソースコード:
//IssueProfileViewController.h class implements NSFetchedResultController delegate methods
- (NSFetchedResultsController*)fetchedResultsController{
if (_fetchedResultsController == nil) {
NSManagedObjectContext *managedObjectContext = self.issue.managedObjectContext;
NSFetchRequest *aFetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"IssueHistoryItem" inManagedObjectContext:managedObjectContext];
[aFetchRequest setEntity:entity];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"created" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
//NSPredicate *predicate = [[NSPredicate predicateWithFormat:@"issue == %@ && isComment == NO", self.issue] retain];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"issue == %@ && isComment == NO", self.issue];
[aFetchRequest setSortDescriptors:sortDescriptors];
[aFetchRequest setPredicate:predicate];
NSFetchedResultsController *aFetchedResultsController =
[[NSFetchedResultsController alloc] initWithFetchRequest:aFetchRequest
managedObjectContext:managedObjectContext
sectionNameKeyPath:nil
cacheName:nil];
[aFetchRequest release];
//[predicate release];
[sortDescriptors release];
[sortDescriptor release];
_fetchedResultsController = aFetchedResultsController;
_fetchedResultsController.delegate = self;
}
return _fetchedResultsController;
}
-(void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
[self.tableView beginUpdates];
}
-(void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
[self.tableView endUpdates];
}
-(void)controller:(NSFetchedResultsController *)controller
didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath
forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath {
NSArray *paths;
// NSIndexSet *section = [NSIndexSet indexSetWithIndex:[newIndexPath section]];
NSIndexPath *cellContentIndexPath;
switch (type) {
case NSFetchedResultsChangeInsert:
// paths = [NSArray arrayWithObject:newIndexPath];
if (![anObject isKindOfClass:[ChangeIssueDimensionValueHistoryItem class]]) {
cellContentIndexPath = [NSIndexPath indexPathForRow:newIndexPath.row inSection:newIndexPath.section];
paths = [NSArray arrayWithObject:cellContentIndexPath];
[self.tableView insertRowsAtIndexPaths:paths
withRowAnimation:UITableViewRowAnimationFade];
[self sendMessageAboutObjectsCountChanged];
}
break;
case NSFetchedResultsChangeDelete:
paths = [NSArray arrayWithObject:indexPath];
[self.tableView deleteRowsAtIndexPaths:paths
withRowAnimation:UITableViewRowAnimationFade];
[self sendMessageAboutObjectsCountChanged];
break;
case NSFetchedResultsChangeMove:
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
[self configureCell:[self.tableView cellForRowAtIndexPath:indexPath]
withIssueHistoryItem:[self.fetchedResultsController objectAtIndexPath:indexPath]];
break;
default:
break;
}
}
ありがとうございました!しかし、正しく理解すれば、新しいエンティティをコンテキストに追加すると、 'processPendingChanges'がトリガされますか?か否か? – hex
はい、NSFetchedResultsControllerのNSManagedObjectContextがprocessPendingChangesを受け取った場合、tableViewは更新されます。コンテキストが保存されると、これが自動的に行われます(ここで繰り返します)。 – JacobFennell