2009-08-04 7 views
2

Core Dataの1つの側面では少し混乱します。つまり、いつ初期のalloc/initルーチンを使うのですか?コアデータを持つオブジェクトを作成し、それを現在の管理オブジェクトコンテキストに保存します。コアデータを使用する際のモデルのインスタンス化の質問

私はそれがむしろあいまいな質問であることを知っています。

私は現在、iPhone上のユーザーの連絡帳をすべて反復処理するアプリケーションを用意しています。そこから、私は「Person」というモデルクラスを作成しました。私は人のループの中でこのようなことをしていました。

Person * person = [[Person alloc] initWithWrapper:mywrapper];

mywrapperにはpersonの属性を持つNSDictionaryが含まれます。後で私の人のオブジェクトで私のアプリのアドレス帳を設定することができるだろう。

私はコアデータを使ってアプリケーションの一部を再構築し始めました。上記の戦略を引き続き使用して住所録を作成しますか?または、代わりに次のようなことをしますか:

Person *person = (Person *)[NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:managedObjectContext]; 

    [person setName:name]; 
    [person setDob:dob]; 

    // Commit the change. 
    NSError *error; 
    if (![managedObjectContext save:&error]) { 
     // Handle the error. 
    } 

問題は、このコードがアプリが起動するたびに実行されることです。アプリが読み込まれるたびに、ストレージメカニズムに人の冗長インスタンスが設定されるため、コアデータを使用しないでください。 NSManagedObject(Personクラス)を変更し、initWithWrapper:メソッドを追加して、通常通りに続行する必要がありますか?

ちょっと混乱していると、明確化が大好きです。

答えて

4

管理対象オブジェクトのコンテキスト外でCore Dataオブジェクトを初期化する必要はありません。単純に意味がありません。あなたはそれをバックアップし、オブジェクトを保存し、それを操作し、あるいは本当にコアデータは、コンテキスト(したがって、モデルとストアコーディネーター)なしで提供することに有用何もできないので、いくつかの

Person *person = [[[Person alloc] init] autorelease];

を持つことは、あなたには良いもしません。

最初にコアデータにオブジェクトを挿入するときは、代わりにalloc - initのコンボを使用する必要があります。これはinitWithEntity:insertIntoManagedObjectContext:の方法です。そしてあなたはそうです、あなたがこのメソッドを呼び出すたびに、新しいオブジェクトをCore Dataコンテキストに挿入して格納し、注意しないと重複したオブジェクトを作成することがあります。

起動するたびにコードを実行している場合は、既存のPersonオブジェクトの一部を返すコアデータクエリを用意し、オブジェクトを追加するだけです(初期化メソッドを使用して)ストアにはまだ存在しません。オブジェクトがすでに存在する場合は、新しいオブジェクトを作成する代わりにオブジェクトを変更します。

このトリックは、このようなものが正しく機能するようになっています。iPhoneアドレス帳の連絡先ごとにCore Dataを取得しないでください。このような多くの小さなフェッチは非常に高価です。あなたは理論的に2つのNSSetsを得ることができます.1つはPersonオブジェクトと1つの連絡先の1つで、連絡先の名字と姓のハッシュのような固有のキーでそれらを比較します。私はあなたに最適化を残します。

キーポイントはこれです:あなたはコンテキストに初めてそのオブジェクトを挿入することを意味しない限り、は、コアデータオブジェクトにallocinitを使用しないでください。既存のオブジェクトを見て、必要に応じて変更してください。

+1

initをオーバーライドしてsuperのinitWithEntity:insertIntoManagedObjectContext:メソッドを呼び出さない限り、 =) –

+0

Touche。よくやった:) – Tim

+0

誰かがinitを上書きする理由を特定できない場合、上記のDaveのように、私は見つけたばかりです:ObjectiveResource(おそらく、他の非コアデータ依存の依存関係)サーバーレスポンスを非マーシャリングするとき)。これは、この正確な問題を回避するためにinitをオーバーライドする必要があるかもしれないことを意味します。 –

0

ええ、あなたのPersonクラスにinitWithWrapperメソッドを追加するのが最も簡単です。これに対する唯一の欠点は、この方法は、あなたがそれを提供する方法を把握する必要がありますので、それは、にオブジェクトを挿入する必要がありmanagedObjectContextかを知る必要があることである

- (id) initWithWrapper:(NSDictionary *)wrapper { 
    NSEntityDescription * person = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:someMOC]; 
    if (self = [super initWithEntity:person insertIntoManagedObjectContext:someMOC]) { 
    //do your wrapperly initialization here 
    } 
    return self; 
} 

:それはこのようなものになるだろう。

言われているように、私はいつもこのパターンを使います。

+0

したがって、アプリが起動するたびにmanagedObjectContextにpersonオブジェクトを追加していますか?もしそれが常に同じ人物のオブジェクトであれば、それぞれ始まりますか?これはデータストア内のPersonオブジェクトを複製しませんか? – Coocoo4Cocoa

+0

@ Coocoo4Cocoa "name =%@"という述語でフェッチ要求を実行し、新しい人を追加する前に結果を返すのはなぜですか。 –

関連する問題