2012-05-14 2 views
5

allItems()addItem:(Item*)itemなどのメソッドを持つCore Dataと対話するためのリポジトリレイヤを作成しました。ここでitemはNSManagedObjectサブクラスです。アイテムを保存する必要があるときは、サブクラスのインスタンスを引数としてリポジトリに呼び出すメソッドを呼び出します。ただし、initイニシャライザを使用することができず、コンテキストがリポジトリ内に隠されているため、これは機能しません。クラス間でNSManagedObjectサブクラスを移送する方法は?

このようなアーキテクチャのオブジェクトを転送するには、どのような方法が最適ですか? ItemDTOをオプションの周りを通過させるのですか?または、サブクラス化されたNSManagedObjectをまったく使用せず、動作するkey/valueを使用するなど、これを解決するより良い方法があります。

+0

問題をもう少し説明できますか?あなたの問題は、リポジトリ層の外に新しい管理対象オブジェクトを作成できない、または後でオブジェクトを保存できないことですか? – jrturton

+0

問題は、コンテキストがリポジトリレイヤー内で「隠されている」ということです。リポジトリレイヤーの外側にコンテキストをリークさせたくありません。私はそれを抽象化の固い地点として使用したいと思います。 – LuckyLuke

+1

すべての管理対象オブジェクトに管理対象オブジェクトコンテキストへのポインタがあることにご注意ください。その特定の猫がバッグの外に出ているので、一種です。 – jrturton

答えて

1

I は、に、モデルカスタムクラスのコンテキストを隠すサンプルプロジェクトをコピー貼り付けしました。branch 10583736

は(それは、単に迅速たとえば、最終的な生産コードではありません、それはマルチスレッドや奇妙なエラーに対処することを期待しないでください)

カスタムクラスにコンテキストを非表示にカスタムメソッドを定義するだけですあなたが通常文脈を要求し、それを使用するあらゆる状況に対処してください。

あなたはコンテキストをさらすことなく、ストア層のためのクラスを定義することができます

@interface DataStore : NSObject 

+ (id)shared; 

- (void)saveAll; 
- (NSEntityDescription *)entityNamed:(NSString *)name; 
/* more custom methods ... */ 
- (NSManagedObject *)fetchEntity:(NSEntityDescription *)entity withPredicate:(NSPredicate *)predicate; 

@end 

を私はいくつかのタイピングを節約するために、すべてのカスタムモデルクラスのための共通の祖先を使用することをお勧めします。このクラスは、DataStoreと直接対話する唯一のクラスです。コンテキストにアクセスすることはできません。

@interface DataObject : NSManagedObject 

+ (NSString *)entityName; 
+ (NSEntityDescription *)entity; 
- (void)save; 
/* more custom methods ... */ 

@end 

最後に、モデルのカスタムクラスを使用すると、おそらく、スーパークラスによって提供されているものを利用して、必要な任意の方法で定義されています。

@interface Card : DataObject 

@property (nonatomic, retain) NSString * question; 
@property (nonatomic, retain) NSString * answer; 
@property (nonatomic, retain) Deck *deck; 

/* return a new card */ 
+ (Card *)card; 

/* more custom methods ... */ 

@end 

マスターブランチは、モデルクラスが取得より一般的なアプローチを持っています文脈とそれで動作します。

3

通常、NSManagedObjectサブクラスを作成するコントローラにはNSManagedObjectContextへのポインタが必要です。このようにして、実際にイニシャライザを呼び出すことができます。

あなたがしようとしている問題は、項目がコンテキストなしで存在できないということです。これは意図的に行われているため、コアデータは、永続ストア内にすでに存在する新しいオブジェクトまたはオブジェクトについて話しているかどうかを知ります。

DTOを使用することもできますが、多くの重複が発生するため、醜いことが起こりやすくなります。私の意見では、コントローラがCore Dataコンテキストを認識できるようにして、アイテム(管理対象オブジェクト)を取得または初期化し、基本的にはNSManagedObjectContextをリポジトリレイヤとして使用するようにしてください。

NSManagedObjectContextはパーシステンス抽象化レイヤーであり、必要に応じて独自のcustom onesを含む他の永続的なストアの実装でバックアップすることができます。

5

あなたが使用しているアーキテクチャは、コアデータには適していないと言えます。それを使い続けるためには、2つのうちの1つをしなければなりません。私は、あなたの "リポジトリ層"がシングルトンとして実装されていると仮定しています。あるいは、少なくとも新しい管理対象オブジェクトを作成するオブジェクトがそのオブジェクトにアクセスできるということです。

  • 管理オブジェクトのコンテキストを他のオブジェクトに公開します。通常は、リポジトリレイヤのプロパティとして公開します。
  • リポジトリレイヤを初期化してオブジェクトを返します。これには、エンティティ名を渡し、適切なエンティティタイプまたはクラスの新しい管理対象オブジェクトを取得する必要があります。

フレームワークと戦って、過度の抽象概念を思いついているのを見つけたら、それは間違っています。

+0

最後のオプションはよかった、ありがとう!非常に賢い – LuckyLuke

関連する問題