1

データモデルに頭を悩ませています。インメモリ オブジェクトが必要な場合にクラスを宣言する方法を示すことから始めましょう。

@interface PlayerState {

  NSSet /* of SavedDie */ *savedDice;
  NSSet /* of SavedDie */ *immediateRolls;

}

@property (nonatomic, retain) NSSet *savedDice;
@property (nonatomic, retain) NSSet *immediateRolls;

@end;

私はちょうど同じタイプのものの2つの異なるグループを持っています. したがって、Core Data でそれをモデル化するとき、PlayerState から SavedDie への 2 対多の関係があればよいと考えました。

逆の関係を定義しようとすると問題が発生します。そもそも、対多関係になぜ逆関係が必要なのかよくわかりません。逆を定義しない場合、一貫性を維持する責任があることは理解していますが、そうしても問題があるようです。

とにかく、所有者と呼ばれる SavedDie に対 1 の関係を定義できますが、私のコードではそれにアクセスする必要はありません。所有者としてのsavedDiceの逆関係を定義できます。次に、immediateRolls の逆関係を所有者として定義しようとすると、savedDice の逆関係として設定が解除されます。もちろん、所有者の逆の関係をsavedDiceとimmediateRollsの両方として設定することはできません。

4

2 に答える 2

3

ここでやろうとしていることを完全に行うことはできません。私があなたを正しく理解しているなら、あなたはダイに単一の所有者関係を持たせたいのですが、playerStateには2つの異なる保存された即時の関係があり、それぞれが所有者にバックリンクされています。CoreDataはこれを許可しません。

モデルを少し考え直す必要があります。おそらく、SavedDieオブジェクトに、それが「保存された」ロールであるか「即時の」ロールであるかを示すフラグを追加します。次に、動的プロパティを追加して、そのフラグに基づいて、保存されたばかりのサイコロまたは即時のサイコロをフェッチします。片道1つの関係。もちろん、これを行う方法は他にもあります。

于 2010-08-22T01:56:12.117 に答える
2

上記の例とは異なり、Core Data は関係グラフも維持する必要があるため、Core Data でこれを直接行うことはできません。

これを理解するために、上記のコード例を使用して関係を手動で設定するとします。との にSavedDie保存されているクラスがあるsavedDiceとします。各インスタンスが を参照するようにしたい場合、所有者へのポインターを作成するのは簡単ですが、それがどのプロパティに格納されているかをどのように知ることができますか。さらに重要なことは、同じオブジェクトが最終的に両方のプロパティまたは 2 つ以上の個別のオブジェクトで?immediateRollsPlayerStateSavedDiePlayerStatePlayerStatePlayerStateSavedDiePlayerState

Core Data は、これらすべてを自動的に管理するために作成され、エンティティ グラフを使用して管理します。エンティティはクラスではありません。代わりに、それらは主にオブジェクト間の関係の抽象的な表現です。エンティティ グラフでは、1 つのエンティティに別のエンティティとの 2 つの関係を持たせることはできません。これは、ライブ データ オブジェクトのどのインスタンスが相互に関連しているかを追跡することが不可能になるためです。

問題を解決するには 2 つの方法があります。

(1) エンティティの継承を使用する: エンティティを作成し、Dieエンティティに必要なすべての属性を設定します。SavedDie次に、 との 2 つのサブエンティティを作成しますImmediateDie。次に、関係を設定します。

PlayerState.savedDie<-->SavedDie.playerState 
PlayerState.immediateDie<-->>ImmediateDie.playerState

(2) 取得した関係を使用する: この場合、1 つのDieエンティティと 1 つの関係があります。

PlayerState.Die<-->>Die.playerState

...しかし、Die各インスタンスを保存済みまたは即時にする属性があります。次に、述語がそれぞれフラグの異なる状態を検索する 2 つのフェッチされた関係を作成します。

(3) リンク エンティティを使用する: この手法では、中間エンティティを使用して、次のように複数の関係で 2 つの主要なエンティティを結び付けます。

PlayerState{
    //...some attributes
    savedDice<-->>PlayerToSavedDie.playerState
    immediateDice<-->>PlayerToImmediateDie.playerState
}

ToDie{
    die<-->SaveDie.player
}
PlayerToSavedDie:ToDie{ //...subentity of ToDie
    //... no attributes
    playerState<<-->PlayerState.savedDice
}

PlayerToImmediateDie:ToDie{ //...subentity of ToDie
    //... no attributes
    playerState<<-->PlayerState.savedDice
}

Die{
    player<-->ToDie.die
}

Dieこのようにして、1 つのリンク関係を削除して別のリンク関係を作成するだけで、インスタンスを関係の周りに移動できます。それに対するDie.playerポイントは、またはその関係でToDieどちらかを受け入れるためです。PlayerToSavedDiePlayerToImmediateDie

これらの手法のどれを使用するかは、データ モデルのニーズによって異なります。1 つの関係にある論理 Die オブジェクトが別の関係に決してジャンプしない場合は、(1) を使用します。保存または即時データが論理 Die オブジェクト自体の重要な属性である場合は、(2) を使用します。論理 Die オブジェクトがリレーションシップ間を移動する必要があり、保存されたデータまたは即時データが論理 Die オブジェクトの一部でない場合は、(3) を使用します。

これはすべて大変な作業に思えるかもしれませんが、重要なことを 1 つ覚えておく必要があります。関係は、属性と同じように重要です。その関係が、モデルがシミュレートする現実世界のオブジェクト、イベント、または条件を反映していない場合、モデルは機能しません。人間関係について考え、管理することに時間を費やすことを期待する必要があります。

Core Data を使用すると、関係管理が 100 倍簡単になりますが、それでも多少の作業が必要です。

于 2010-08-22T23:32:05.747 に答える