2009-08-12 12 views
67

iPhone Core Data Templateで、AppleはコアデータスタックをApp Delegateに配置します。"Core Data Stack"をCocoa/Cocoa Touchアプリケーションに配置する場所

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

通常、この機能を独自のクラスにカプセル化していますか、それともApp Delegateに残していますか?

答えて

39

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

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

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

[[UIApplication delegate] managedObjectContext]; 
+2

依存性注入を使用していないのは、最初にコアデータを使用し始めたときには間違ったデザインでした。最近、私はあなたが概説したのと同じアプローチを取っています。主な相違点は、コアデータスタックコードをAppDelegateから論理的に分離する場合のみ、コアデータスタックコードをNSManagedObjectコンテキストのカテゴリに入れたことです。理論的には、シングルトンのようなカテゴリーを使用することもできますが、あなたが言ったように、「アプリケーションの剛性」を導入することはしません。さらに、Core Dataスタック用のカスタムコードをいくつか使用しています。これにより、このコードを新しいプロジェクトに簡単にドロップできます。 –

+1

私はあなたと一緒に、コアデータスタックを作成するためのApp Delegateを使用しています。私は、ルートビューコントローラとしてUITabBarControllerを使用していますが、MainWindow.xibに存在するため、そのコントローラオブジェクトにコンテキストを伝播する方法がわからず、ManagedObjectContextへのポインタを割り当てる方法がわかりません。私はこれについて別の質問を掲示していると思います。 – mvexel

+1

アップルのドキュメントでは、「ビューコントローラを作成するときに、使用するコンテキストを渡します。しかし、私はこれがどのように行われているか見ていない。ストーリーボードを使用している場合、メインビューコントローラはストーリーボードを介して作成されます。どのようにコンテキストを渡すのですか? –

28

私は私のコアデータ管理を可能にするシングルトンクラスを持っており、私はアプリケーションデリゲートに残さないでください。私は表示されません)

1:私はむしろ、私は次のような理由からアプリケーションデリゲート内のコアデータ・ロジックを残すなどなど

+1

は私に実用的なサウンド:

(*)なしの例では、使用してコンテキストを取得します。私はリンゴそれには、アプリケーションの代理人が含まれて驚いています。 –

+4

これはおそらく、アプリケーションのデリゲートがシングルトンのようなものなので、それを置くのに便利な場所ですが、どうやってどこに行うのかを示したいからです。 – Daniel

+3

シングルトンのコアデータコントローラオブジェクトを持つことは全く意味があります。 すべてのプロジェクトで再利用できるように抽象化しました。 +1 – stigi

11

特定のオブジェクトを取得するようconvinieceのために必要がある場合があります方法でアプリのデリゲートクラスを乱雑ありませんこのコードを他のクラスで動かすことの本当の利点:コアデータモデルは実際にアプリケーションの基本的な部分であるため、委任の概念はAppデリゲートによって処理されるコアデータロジックによって完全に満たされます。

2)私が見たサンプルコードの中には、アップルのサンプルを含めて、コアデータはApp Delegateによって処理されています。

3)コアデータブックであっても、アプリケーションデリゲートがコアデータに関連するコードを処理するのが一般的です。

4)個人的に私は、可読性などが実際にコアデータの特別なクラスを持つことで改善されるとは考えていませんが、これは個人的な趣味の問題です。私にとっては、機能を維持しながらシンプルさが重要です。

+0

私は通常、アプリケーションデリゲートにコアデータスタックも表示します。しかし、私が見ているコードは、通常、説明のために作成されています。何かを実装する実際の方法は、そのような例とは時々異なります。正直なところ、Appleのサンプルコードを盲目的にフォローしたくなかった。私はあなたが正しいと思う傾向があります。どちらかといえば、いくつかの利点を持って個人的な好みの問題になると仮定します。 –

+3

また、引数2と3は、チュートリアルやサンプルでは、​​あなたが提示しようとしているものに関係のないコードをできるだけ最小限に抑えようとしているからです - シングルトンの仕組みを実装することは、簡単な例であるはずのもの。 App Delegateでこれらのことを維持することを嫌っているのは、App Delegateについて知っておく必要のあるものの数が増えるからです。 –

+0

"委任の概念は、アプリケーションデリゲートはコアデータモデルがアプリケーションの基本的な部分であるため、いいえ、UIApplicationは、Core Data機能の責任を委任していません。永続ストアはアプリケーションレベルの関心事ですが、UIApplicationDelegateの一部ではありません。 – quellish

10

あなたのケースでは、「コアデータスタックは誰に属しているのですか」という疑問があります。データそのものはアプリケーションの本当のところですね。 (Mac上のCFコアデータ。一度に複数のドキュメントを処理できるアプリケーションがあるため、コアデータスタックは各ドキュメントに属します)。

すべてのCocoa/Cocoa Touchアプリケーションでは、App Delegate通常、アプリケーションの動作をカスタマイズするための好ましい方法です。したがって、これはコアデータスタックにとって自然な場所です。

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

は、私は通常、これらの場合に行うことは、このような関数(ないメソッド)を記述している:

さて、私はあなたが抱えている疑いがある問題は、それが常にのようなものを書くことは誤り感じているということです

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

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

+1

それは面白いです。それはちょうど私が気に入らないコードです。私はApp Delegateへのファイル保存情報の実行を嫌っています。それは "間違っている"と感じました。それは、他の開発者がこの状況をどのように処理したかに疑問を感じました –

+1

最初のコードスニペットが間違っていると感じる理由は、そのコードのにおいが原因です。便利な機能でそれを包むだけで消臭です。そのコンテキストを必要とするオブジェクトにコンテキストを渡すだけで、(プロパティインジェクションを使用して)ほとんどより簡単です。 –

+2

このようなアプリケーションデリゲートからコンテキストを取得しないでください。すべてのAppleの例に示すように、あるView Controllerから別のView Controllerへコンテキストを渡す必要があります。 – mmalc

4

私は、アプリケーションの代理人にモデルの開始位置を知らせ、モデルに管理されたオブジェクトのコンテキストがどこにあるのかを知らせるのが好都合です。モデルのコアデータ - "ness"は、モデルの実装の詳細のようですが、コントローラのクラス(アプリケーションデリゲートのような)は "モデルに関するこの情報を私に与えてください"と尋ねるだけで、モデルは答える方法を知っているべきですその質問。したがって、コントローラオブジェクトを通じてコアデータオブジェクトを利用できるようにすることは、漏れ抽象化のように思えます。

+0

iPhone開発で問題になったことは何ですか? NSFetchedResultsControllerを使用して設定します。 NSFetcheResultsControllersを設定して返す方法も "Model"にすることができますが、モデルクラスが少し膨らんでしまうようです。私はNSFetchedResultsControllerersがコントローラーとモデルコードの間の線をぼやけさせるように感じる(必ずしも悪い方法ではない)。私は最近、これといくつかのアイデアを新しい構成に取り入れました(新しい回答が追加されました)。 –

+0

私は@Grahamに同意します。これが私のやり方です。あなたの 'UIViewControllers'は' NSManagedObjectContext'を混乱させる必要はないはずです。モデルと話して、必要なものを尋ねるだけです。その情報を取得する仕組みは、私のView Controllerには関係ありません。 – kubi

6

私はこれを新しい回答で単にリストします。(私は以前のFJSCoreDataStackクラスを廃止しました)

これを処理する新しい方法は、NSManagedObjectContextのカテゴリを使用することでした。

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

これは私のアプリデリゲートのうちのすべてを保持し、私はそれを使用することを選択しなければならないシングルトンのアクセスを提供します:アイブ氏は、次のクラスのメソッドを追加しました。しかし、私はまだApp Delegateからの依存関係注入を使用しています(mmalcは言っていますが、これは自分のコードに柔軟性をもたらしません)。私は単純にすべての "コアデータスタック"コードをNSManagedObjectCOntextカテゴリに移動しました。

私は素敵な "スクラッチパッドコンテキスト"メソッドを持っているので、私は参照を渡すのが好きです。これは、私が "defaultManagedObjectContext"にコミットしていないので、View Controllerを柔軟に保ちます。また

iPhoneの世界での会話に関連する(とあなたのアーキテクチャ上のベアリングを有していてもよい): NSFetchedResultsController and constructing NSFetchRequests

関連する問題