すべてのコア データ オブジェクトは、管理対象オブジェクト コンテキストを介してアクセスする必要があります。
NSFetchRequest をデータベース クエリの表現と考えてください。(MOC)にデータをフェッチするように指示するときはNSManagedObjectContext
、フェッチ要求を与えるので、何をフェッチするかがわかります。
ここで、テーブル ビューがあるとします。フェッチを行い、表示する必要のないものであっても、すべてのデータを取得します。テーブル ビューが変更されるたびに、データを再フェッチする必要があります。フェッチ リクエストを使用するだけでも問題はいくつかありますが、それは可能です。
これらの問題の一部を解決するには、NSFetchedResultsController
(FRC) を入力します。その時点で実際に必要なオブジェクトのみをメモリ内に保持するようにデータベースを管理します。さらに、MOC にフックするため、データベースが変更されると、自身のデータが自動的に変更されます。
したがって、FRC を作成し、それにフェッチ要求を与えます。現在、データを管理しているため、必要なものだけがメモリに保持されます。ただし、何を取得するかを伝える必要があり、いつデータを取得するかを伝える必要があります。
したがって、のNSFetchedResultsControllerDelegate
出番です。
デリゲートは、テーブル ビュー (または他のコンポーネント) と FRC の間の接着剤です。デリゲート メソッドは、どのデータをいつ取得するかを FRC に通知し、それをテーブル ビューに渡す通信チャネルです。
編集
はい、FRC は実際のデータ部分を管理します。ただし、データが変更された場合、データを見ている人に通知する方法が必要です。それがデリゲートの目的です。デリゲート メソッドを見て、別の攻撃を行いましょう。
データベースが何らかの方法で変更されたと想像してください。FRC は、その特別な魔法の呪文によって変化に気づき、新しい iPhone を持った 10 代の若者のように、誰かに知らせる必要があります。
具体的には、あなたの場合、データをユーザーに表示する責任があるテーブルビューに伝える必要があります。では、データが変更されたことをテーブル ビューに伝えるにはどうすればよいでしょうか。iOSでは実際にいくつかのパターンが使われていますが、今回はデリゲートを使用します。
FRC からこの情報を受け取りたい人は、デリゲート メソッドを実装するオブジェクトへのポインターを彼に渡します。FRC が関心のあるユーザーに通知する場合、デリゲートとして指定されたオブジェクトで適切なメソッドを呼び出します。
変化が起こったと考えてください。FRC コードは次のようになります (非常に単純化されていますが、アルゴリズムのアイデアを提供するためです)。
[delegate controllerWillChangeContent:self];
// Process all the changes...
for (SectionChangeInfo *info in changedSections) {
[delegate controller:self didChangeSection:info.sectionInfo atIndex:info.index forChangeType:info.changeType];
}
for (ObjectChangeInfo *info in changedObjects) {
[delegate controller:self didChangeObject:info.object atIndexPath:info.indexPath forChangeType:info.changeType newIndexPath:index.newIndexPath];
}
[delegate controllerDidChangeContent:self];
したがって、FRC は、変更が発生したときにその変更について「誰か」に伝えることができます。あなたの場合、FRC にデリゲートを与えると、それらのメソッドが呼び出されるため、変更が発生したときに変更を処理する機会が与えられます。
もう 1 つのデリゲート メソッドは、セクション タイトルとして何を使用するかをデリゲートに問い合わせるために呼び出されます。したがって、FRC が何を使用するかを知る必要があると仮定すると、次のように呼び出されます...
NSString *sectionTitle = [[section substringToIndex:1] uppercase];
if ([delegate respondsToSelector:@selector(controller:sectionIndexTitleForSectionName:)]) {
sectionTitle = [delegate controller:self sectionIndexTitleForSectionName:section];
}