5

allItems()、などのメソッドを持つコアデータと対話するためのリポジトリレイヤーを作成しましたaddItem:(Item*)item。ここで、アイテムはNSManagedObjectサブクラスです。アイテムを保存する必要がある場合は、リポジトリのメソッドを呼び出して、サブクラスインスタンスを引数として渡します。initただし、初期化子を使用できず、コンテキストがリポジトリ内に隠されているため、これは機能しません。

このようなアーキテクチャがある場合、オブジェクトを転送するための最良の方法は何ですか?ItemDTOをオプションの周りに渡すことですか?または、サブクラス化されたNSManagedObjectをまったく使用せず、機能するキー/値を使用するなど、これを解決するためのより良い方法はありますか。

4

3 に答える 3

5

あなたが使用しているアーキテクチャは、コア データには適していないと思います。それを使い続けるには(そうすべきです)、2つのことのいずれかを行う必要があります。「リポジトリレイヤー」がシングルトンとして実装されているか、少なくとも新しい管理対象オブジェクトを作成するオブジェクトがそれにアクセスできると想定しています。

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

フレームワークと格闘し、過度の抽象化を考え出す場合、それは間違っています。

于 2012-05-21T20:55:47.577 に答える
3

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

あなたがやろうとしていることの問題は、アイテムが文脈なしでは存在できないということです。これは意図的に行われるため、Core Dataは、新しいオブジェクトについて話しているのか、永続ストアに既に存在するオブジェクトについて話しているのかを認識します。

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

これは永続性抽象化レイヤーであり、必要に応じて、独自のカスタムNSManagedObjectContext実装を含め、他の永続ストア実装でバックアップできることを忘れないでください。

于 2012-05-21T19:14:49.683 に答える
1

モデルカスタムクラスからコンテキストを非表示にするサンプルプロジェクトをコピーして貼り付けました:ブランチ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

マスターブランチには、モデルクラスがコンテキストを取得して操作する、より一般的なアプローチがあります。

于 2012-05-26T18:38:20.803 に答える