UITableViewController とともに NSFetchedResultsController を使用しています。
UITableView セクションのラベルとして使用する Core Data モデルに一時フィールドを作成しました。フィールドの名前は「sectionIndex」です。私のアプリケーションでは、「クライアント」エンティティには多くの「ジョブ」(1 対多数) があります。そのため、ジョブを取得するクエリは、関連付けられた「クライアント」の名前で (セクションを介して) それらをグループ化します。
このメソッドは、'Job' エンティティのカテゴリとしてコード ベースに実装しました。
@implementation Job (TransientMethods)
- (NSString*)sectionIndex {
NSLog(@"JobWrapper.Job.sectionIndex: %@", self.client.name);
return self.client.name;
}
@end
文字列「sectionIndex」は、NSFetchedResultsController の init メソッドに sectionNameKeyPath 引数として渡されます。
シミュレーターからアプリを消去すると、アプリケーションの初回実行時に、Jobs のフロント ページが正しく取得され、ここにリストされている sectionIndex メソッドごとに Job の Client.name によってグループ化されます。ログを見ると、文字通り、この sectionIndex メソッドが複数回呼び出されていることがわかります。
ただし、アプリケーションの後続の実行では sectionIndex メソッドは呼び出されません ... それでも、セクション ラベルは前回の実行の値で表示されます。それはどのように起こっていますか?実行間で魔法のキャッシュが行われていますか?
その行動は、より大きな問題につながります。UITableView を見ているときに、わずかに異なる述語を使用して NSFetchedResultsController を解放して割り当てると、結果セットが同じサイズである場合、...すべての新しい結果に対して同じ元のセクション名が表示されます!
もちろん、新しいログ エントリはありません。これは、列が検索されないことを意味します。これは、コードが一時フィールドを呼び出したり検索したりしないことを意味します。それらのフィールドに障害がないかのようです。
これで、代替クエリが異なる数の結果を返す場合、セクション名がロードされます。IE: その場合、ログには、バー ボタンを押すたびに、'sectionIndex' メソッドが呼び出され、対応するラベルが UITableView に表示されます。
これはクレイジーです。2 つの「アクティブな」ジョブと 2 つの「非アクティブな」ジョブがあり、バー ボタンを使用して対応するクエリを前後に切り替えている場合、最初のクエリに関連付けられたセクション ラベルがすべて表示されます。後続のテーブル ビュー。
結果セット内の結果の数が異なる場合、sectionNameKeyPath フィールドは FetchedResultsController によってのみ呼び出されるようです。実際の結果は異なります-ジョブ名は実際の行に正しく表示されます-しかし、セクションラベルが正しくないか、NSFetchedResultsControllerにセクションラベルを正しく要求しているとは思いません。私は以下を使用しています:
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
int count = [[results_ sections] count];
if (count > section) {
id <NSFetchedResultsSectionInfo> sectionInfo = [[results_ sections] objectAtIndex:section];
return [sectionInfo name];
}
return nil;
}
ここで、results_ は、クエリごとに再構築している NSFetchedResultsController です。
何か不足していますか?その Core Data キャッシュを手動でクリアして、スマートになるのをやめ、すべてのクエリで確実に sectionNameKeyPath を検索する方法はありますか?
その価値のために、xcdatamodel のフィールドの「一時的」オプションのチェックを外しましたが、同じ結果が得られました。
これによる最後の例外の 1 つは、最初のジョブを非アクティブ (デフォルトのスタートアップ ビューではない) として作成すると、アクティブ ジョブも作成すると、非アクティブ セクション ラベルが両方に貼り付けられることです。さらに、アプリケーションをシャットダウンして最初からやり直すと、Inactive セクションのラベルがまだ表示されます --- タイトル画面で、まったく別のラベルを表示しているはずの Active Job を表示しているにもかかわらず。
これはコアデータの問題だと思わざるを得ません。アプリケーションを再起動するとデータが返されるというのは意味がありません。