web-dev-qa-db-ja.com

Cocoa / Cocoa Touchアプリケーションで「コアデータスタック」を配置する場所

IPhoneコアデータテンプレートでは、Apple=はコアデータスタックをApp Delegateに配置します。

ただし、私の最初の傾向は、このコードを独自のクラスに移動することです。このクラスの責任は、コアデータスタックの管理を処理することです。

通常、この機能を独自のクラスにカプセル化しますか、それともアプリデリゲートに残しますか?

67
Corey Floyd

概要:Core Dataスタックを管理するためにシングルトンを作成する必要はありません。実際、そうすることは逆効果になる可能性があります。

Core Dataスタックはたまたまアプリケーションデリゲートによって作成されます。ただし、重要なのは、すべての例が示すように、スタック(主に管理対象オブジェクトのコンテキスト)はnotであり、stack(*)から直接取得されることです。代わりに、コンテキストが最初のビューコントローラーに渡され、コンテキストまたは管理対象オブジェクトから、1つのビューコントローラーから次のビューコントローラーに渡されます( コアデータスタックへのアクセス で説明されています)。これは、iPhoneのすべてのアプリケーションの基本的なパターンに従います。データまたはモデルコントローラーを1つのビューコントローラーから次のビューコントローラーに渡します。

ここで説明するシングルトンの典型的な役割は、モデルコントローラーとしての役割です。 Core Dataでは、管理対象オブジェクトのコンテキストはすでにモデルコントローラーです。また、必要に応じてスタックの他の部分にアクセスすることもできます。さらに、(ドキュメントで説明されているように)状況によっては、個別のアクションセットを実行するために異なるコンテキストを使用したい場合があります。したがって、View Controllerの適切な通貨単位は、通常は管理対象オブジェクトのコンテキストであり、それ以外の場合は管理対象オブジェクトです。スタックを管理する(およびコンテキストを取得する)シングルトンオブジェクトを使用して渡すと、通常、せいぜい不要なレベルの間接参照が発生し、最悪の場合、不必要なアプリケーションの剛性が発生します。

(*)次を使用してコンテキストを取得する例はありません。

[[UIApplication delegate] managedObjectContext];
39
mmalc

私は自分のコアデータ管理を任せるシングルトンクラスがあり、それをアプリデリゲートに任せません。特定のオブジェクトを取得するなど、確信する必要があるかもしれないメソッドでアプリデリゲートクラスを混乱させない

28
Daniel

次の理由で、コアデータロジックをアプリデリゲートに残しています。

1)このコードを他のクラスに移動することに実質的な利点はないと思います。委任の概念は、コアデータモデルが実際にアプリケーションの基本的な部分であるため、アプリデリゲートによって処理されるコアデータロジックによって完全に満たされます。

2)Appleサンプルを含む)で見たすべてのサンプルコードでは、コアデータはアプリデリゲートによって処理されます。

3)コアデータブックでも、アプリデリゲートにコアデータ関連コードを処理させるのが一般的です。

4)個人的には、コアデータのアドホッククラスを使用することで読みやすさなどが実際に改善されるとは思いませんが、これは個人的な好みの問題であり、ここではどのアプローチが最適であるかについては触れません。私にとって、機能性を維持しながらシンプルにすることは重要です。

11
Massimo Cafaro

あなたの場合、私が自分に尋ねる質問は、「Core Dataスタックは誰に「属する」のですか?」です。データ自体は本当にアプリケーションの領域ですよね? (MacのC.F. Core Data。一度に複数のドキュメントを処理できるアプリケーションがあるため、Core Dataスタックは各ドキュメントに属します。)

Cocoa/Cocoa Touchアプリケーションでは、通常、アプリケーションデリゲートがアプリケーションの動作をカスタマイズするための推奨手段であるため、これがコアデータスタックの自然な場所です。

さて、あなたが持っていると私が疑っている問題は、次のようなものを常に書くことは間違っていると感じることです:

NSManagedObjectContext *context = [(MyAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];

これらの場合に私が通常行うことは、次のような(メソッドではなく)関数を記述することです。

NSManagedObjectContext *UIAppManagedObjectContext() {
    return [*(MyAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
}

NSPersistentStoreCoordinatorNSManagedObjectModelにも同様の関数を記述します。これらもすべてアプリケーションレベルのオブジェクトであるため、これらすべてをApp Delegateの.h/.mファイルに入れました。

10
Alex

これを新しい答えにリストします。 (私はこれを支持するために以前のFJSCoreDataStackクラスを破棄しました)

これを処理する新しい方法は、NSManagedObjectContextのカテゴリを使用することです。次のクラスメソッドを追加しました。

+ (NSManagedObjectContext *)defaultManagedObjectContext;
+ (NSManagedObjectContext *)scratchpadManagedObjectContext;
+ (NSManagedObjectModel *)managedObjectModel;
+ (NSPersistentStoreCoordinator *)persistentStoreCoordinator;
+ (NSString *)applicationDocumentsDirectory;

これにより、すべてがアプリデリゲートから除外され、使用することを選択した場合にシングルトンアクセスが提供されます。ただし、私はまだアプリデリゲートからの依存性注入を使用しています(mmalcが言ったように、コードに柔軟性がありません)。すべての「コアデータスタック」コードをNSManagedObjectCOntextカテゴリに移動しただけです。

特にニースの「スクラッチパッドコンテキスト」メソッドがあるので、リファレンスを渡すのが好きです。これにより、「defaultManagedObjectContext」にコミットしていないため、ビューコントローラーの柔軟性が維持されます。

IPhoneの世界での会話にも関連します(ご使用のアーキテクチャーに関係している可能性があります): NSFetchedResultsControllerおよび構築NSFetchRequests

6
Corey Floyd

アプリのデリゲートにモデルの開始場所を知らせ、モデルに管理オブジェクトコンテキストの場所を知らせたいと思います。モデルのコアデータ-「ネス」は、モデルの実装の詳細のように思えます。コントローラークラス(アプリデリゲートなど)は、「モデルに関するこの情報を教えて」と尋ねるだけで、モデルは答える方法を知っているはずですその質問。そのため、コントローラオブジェクトを介してCore Dataオブジェクトを利用できるようにすることは、抽象的ではないように見えます。

4
user23743