Core Dataについて

CoreDateとは

  • Modelオブジェクトをファイルに保存したり、ファイルから復元したりする
  • アーカイブよりも多機能
    • Modelオブジェクトの変更履歴(アンドゥとレドゥ、オブジェクト間の相互関係の管理)
    • Modelオブジェクトのサブセットだけをメモリ内の保持する事ができる
    • GUIベースのエディタでModelクラスを定義する事ができる
    • データストアのバージョン管理および移行のためのインフラストラクチャ

登場人物

  • 管理オブジェクト(Managed Object Model)
    • NSManagedObjectまたはNSManagedObjectのサブクラス
    • 概念的にはデータベースのテーブル内のレコードオブジェクト
    • MVCのModelオブジェクト
  • 管理オブジェクトコンテキスト(Managed Ojbject Context)
    • NSManagedObjectContextのインスタンス
    • 管理オブジェクトのコレクションを管理
    • Modelオブジェクトのグループを形成
    • ライフサイクル管理、妥当性検証、関係の管理、アンドゥ/リドゥまで管理
  • 管理オブジェクトモデル
    • NSManagedObjectModelのインスタンス
    • データベースを定義するスキーマオブジェクト
    • モデルはエンティティ記述オブジェクトのコレクション
  • 永続ストアコーディネータ
    • 永続ストアコーディネータはNSPersistentStoreCoordinatorのインスタンス
    • 永続オブジェクトストア(外部ストア:ファイルなどを指す)のコレクションを管理
    • アプリケーション内のオブジェクトとデータベース内のレコードをマッピングする

サンプル

AppleのDeveloper Libraryにあるドキュメントをもとに使ってみる

プロジェクトの作成

プロジェクトの作成の作成じに、Core Dataを使用するにチェックを入れる (Use Core Data for storage)
  • アプリケーションデリゲートクラス
    • プロパティーが自動生成される
// 管理オブジェクトコンテキスト
@property (nonatomic, retain, readonly) NSManagedObjectContext
*managedObjectContext;
// 管理オブジェクトモデル
@property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel;
// 永続ストアコーディネータ
@property (nonatomic, retain, readonly) NSPersistentStoreCoordinator
*persistentStoreCoordinator;
- (NSURL *)applicationDocumentsDirectory;
- (void)saveContext;
  • Core Dataのモデル(.xcdatamodeld)ファイル(通常、管理オブジェクトモデルと呼ばれる)

データのモデリング

xcodeで[プロジェクト名].xcdatamodelを選択後、Entityを追加、そのEntityに対してAttributeを追加していく

カスタム管理クラスオブジェクト

通常のクラスファイルを作成する手順で「Managed Object Class」を選択
Entityが選択できるので、先ほど作成したEntityを選択する
プロパティはsynthesizedではなく、dynamicとなる。コンパイル時ではなく、実行時にアクセサーを生成する
実装ファイル(Event.m)にはdeallocがない。オブジェクトのライフサイクルはCoreDataが行うため

管理クラスオブジェクトの生成/保存

通常は、NSEntityDescriptionの簡易メソッド(insertNewObjectForEntityForName:inManagedObjectContext:)を使用して管理オブジェクトを作成
指定したエンティティーに対応するクラスを初期化し、コンテキストに挿入する
オブジェクトを追加したり変更したりすると、その変更はsave:が呼び出されるまではメモリ内に保持される

// Eventエンティティの新規インスタンスを作成して設定する
Event *event = (Event *)[NSEntityDescription insertNewObjectForEntityForName:@"Event" inManagedObjectContext:managedObjectContext];

// ここでeventに対してデータを設定

// データの保存
NSError *error = nil;
if (![managedObjectContext save:&error]) {
    // エラーを処理する
}

管理オブジェクトのフェッチ

フェッチ要求では、最低限、関心のあるエンティティを指定
オブジェクトが持つ値に関する制限を指定したり、オブジェクトを返す順番を指定したりすることも可能

NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event"
inManagedObjectContext:managedObjectContext];
[request setEntity:entity];

// ソート
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc]
initWithKey:@"creationDate" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor,
nil];
[request setSortDescriptors:sortDescriptors];
[sortDescriptors release];
[sortDescriptor release];

// 実行
NSError *error = nil;
NSMutableArray *mutableFetchResults = [[managedObjectContext
executeFetchRequest:request error:&error] mutableCopy];
if (mutableFetchResults == nil) {
    // エラーを処理する
}

[self setEventsArray:mutableFetchResults];
[mutableFetchResults release];
[request release];

管理オブジェクトの削除

レコードを削除するには、NSManagedObjectContextのdeleteObject:メソッドを使用する
登録同様にseveメソッドを読んで、反映させる

// 指定のインデックスパスにある管理オブジェクトを削除する。
NSManagedObject *eventToDelete = [eventsArray
objectAtIndex:indexPath.row];
[managedObjectContext deleteObject:eventToDelete];

// 変更をコミットする。
NSError *error = nil;
if (![managedObjectContext save:&error]) {
 
はじめてのCoreDataではまりどころ
"The operation couldn’t be completed. (Cocoa error 134100.)"
スキーマを変更する場合、マイグレーション処理をしましょうってことらしい。
アプリを削除して再度実行すればなおる

0 件のコメント:

コメントを投稿

ReactNativeでAndroid対応する話

前提 ReactNativeでiOS版のアプリをリリースしていて、Android版をリリースする話 トラブルシューティング Build.VERSION_CODES.Q が存在しないエラー compileSdkVersionを29以上にすると解決 メモリー足りないエラー Execu...