CoreDataBooks の動作はこんな感じ。
リストに詳細表示、それと項目の編集を行う3つのビューから構成される。データの格納に CoreData を採用していて UITableView との連携に NSFetchedResultsController を使っている。
NSFetchedResultsController の使い方を理解するためにこのコードを参考にしつつ、(テーブルが一つで)構造が単純な OneLiner を NSFetcedResultsController を使うバージョンに書き換えてみる。
MainViewController.h
@interface MainViewController : UIViewController {
NSPersistentStoreCoordinator* persistentStoreCoordinator;
NSManagedObjectContext* managedObjectContext;
NSFetchedResultsController* fetchedResultsController;
}
メンバ変数に NSFechedResultsController を追加。
MainViewController.m
- (void)setupFetchedResultsController
{
// [1] Persistent Store Coordinator
persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[NSManagedObjectModel mergedModelFromBundles:nil]];
NSError* error = nil;
NSString* filepath = [NSString stringWithFormat:@"%@/%@",
[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0],
@"memo.db"];
[persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:[NSURL fileURLWithPath:filepath]
options:nil
error:&error];
if (error) {
NSLog(@"[1] %@", error);
}
// [2] Managed Object Context
managedObjectContext = [[NSManagedObjectContext alloc] init];
[managedObjectContext setPersistentStoreCoordinator:persistentStoreCoordinator];
// [3] Fetched Results Controller
// Fetch Request
NSFetchRequest* request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:@"Memo"
inManagedObjectContext:managedObjectContext]];
[request setIncludesSubentities:NO];
// Sort Descriptor
NSSortDescriptor* sortDescriptor =
[[NSSortDescriptor alloc] initWithKey:@"title"
ascending:YES];
[request setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]];
// Fetched Result Controller
fetchedResultsController =
[[NSFetchedResultsController alloc]
initWithFetchRequest:request
managedObjectContext:managedObjectContext
sectionNameKeyPath:nil
cacheName:@"Root"];
[sortDescriptor release];
[request release];
}
セットアップ用のメソッドを用意し、ここで NSPersistentStoreCoordinator, NSManagedObjectContext, NSFectedResultsController の3つのインスタンスを用意する。NSFetchedController には検索条件、ソート条件をあらかじめ渡しておく。
- (void)viewDidLoad {
[super viewDidLoad];
[self setupFetchedResultsController];
NSError* error = nil;
if (![fetchedResultsController performFetch:&error]) {
NSLog(@"%@", error);
}
:
View のロード時にセットアップと読み込み(performFetch)を実行する。
続いて DataSource のコーディング。
- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section
{
id <NSFetchedResultsSectionInfo> sectionInfo =
[[fetchedResultsController sections] objectAtIndex:section];
return [sectionInfo numberOfObjects];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *SimpleTableIdentifier = @"SimpleTableIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SimpleTableIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero
reuseIdentifier:SimpleTableIdentifier] autorelease];
}
NSManagedObject* managedObject = [fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = [managedObject valueForKey:@"title"];
return cell;
}
前回までは呼出される毎に検索をかけていたが、その部分を NSFetchedController にまかせることができるのですっきりした。UITableView 向けにつくられているので Section や NSIndexPath をそのまま扱えるのが便利。
実行してみよう。
動いた。
コンソールを見るとSQLが飛んでいるのは1回のみ(あたりまえだが)。
[Session started at 2009-10-13 06:13:39 +0900.] 2009-10-13 06:13:44.494 OneLiner[8886:207] CoreData: annotation: Connecting to sqlite database file at "/Users/hashi/Library/Application Support/iPhone Simulator/User/Applications/BF9B0A56-4CC4-428A-AB2B-FD1E20BDEAAD/Documents/memo.db" 2009-10-13 06:13:44.500 OneLiner[8886:207] CoreData: sql: pragma cache_size=1000 2009-10-13 06:13:44.501 OneLiner[8886:207] CoreData: sql: SELECT Z_VERSION, Z_UUID, Z_PLIST FROM Z_METADATA 2009-10-13 06:13:44.549 OneLiner[8886:207] CoreData: sql: SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZTITLE, t0.ZPHOTO FROM ZMEMO t0 ORDER BY t0.ZTITLE 2009-10-13 06:13:44.551 OneLiner[8886:207] CoreData: annotation: sql connection fetch time: 0.0019s 2009-10-13 06:13:44.552 OneLiner[8886:207] CoreData: annotation: total fetch execution time: 0.0032s for 18 rows.
SQLiteから取得したデータの管理を NSFetechedResultsController がやってくれるのでこれはいい。
0 件のコメント:
コメントを投稿