web-dev-qa-db-ja.com

NSFetchedResultsController:述語の変更が機能していませんか?

1つの画面に2つのテーブルがあるアプリを書いています。左側の表はフォルダのリストであり、右側の表はファイルのリストを示しています。左側の行をタップすると、右側のテーブルにそのフォルダに属するファイルが表示されます。

ストレージにCoreDataを使用しています。フォルダーの選択が変更されると、右側のテーブルのNSFetchedResultsControllerのフェッチ述部が変更され、新しいフェッチが実行されてから、テーブルデータが再ロードされます。次のコードスニペットを使用しました。

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"list = %@",self.list];
[fetchedResultsController.fetchRequest setPredicate:predicate];
NSError *error = nil;
if (![[self fetchedResultsController] performFetch:&error]) {   
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    abort();
}
[table reloadData];

ただし、フェッチ結果は同じです。フェッチの前後に「述語」をNSLogしましたが、更新された情報で正しくなりました。フェッチ結果は、最初のフェッチと同じままです(ビューがロードされたとき)。

Core Dataがオブジェクトをフェッチする方法(キャッシュシステムはありますか?)にはあまり詳しくありませんが、以前は同様のこと(述語の変更、データの再フェッチ、テーブルの更新)を単一のテーブルビューで行っており、すべてがうまくいきました上手。

誰かが私にヒントを与えることができれば私は非常にありがたいです。

前もって感謝します。

36
Tong Liu

iphone incubator のごく最近のブログ投稿でヒントを見つけるまで、私はほぼ正確にこの問題を抱えていました。

NSFetchedResultsControllerは最初の結果をキャッシュしています。 (おそらく、initWithFetchRequest:managedObjectContext:sectionNameKeyPath:cacheNameに何かが設定されています)

あなたのコード(私のような)はCoreDataサンプルの派生物だと思いますので、それが@ "Root"であると仮定して、述語を変更する前に、

[NSFetchedResultsController deleteCacheWithName:@"Root"];  
56
deafgreatdane

これは私のために働いた:

[NSFetchedResultsController deleteCacheWithName:nil];  
[self.fetchedResultsController.fetchRequest setPredicate:predicate]; 

NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error]) {
    NSLog(@"%@, %@", error, [error userInfo]);
    abort();
} 
2
NSPratik

私のSwiftプロジェクトで同様の問題がありました。これは私のために働きました

NSFetchedResultsController.deleteCache(withName: fetchedResultsController.cacheName)

1
lionserdar

私の場合、deafgreatdaneの答えは機能していません。代わりに私がしたことはおそらく素朴ですが、機能します:

  • configureCell:atIndexPath:メソッドで対応する述語を作成します(tableView:cellForRowAtIndexPath:で呼び出されます)
  • 次に、電話します。
    [_fetchedResultsController.fetchRequest setPredicate:predicate];
    [_fetchedResultsController performFetch:nil];
  • [self.fetchedResultsController objectAtIndexPath:indexPath]を呼び出して、返されたオブジェクトを参照します
1
dobranoc