3

だから私はコアデータに苦労しています。同じことを行うには多くの方法があり、Storyboards と UIManagedDocuments を使用してアプリを構築しようとする場合は、昨年より古いすべてのチュートリアルと例を翻訳シートで読む必要があることがわかりました。今日の質問は、新しい管理対象オブジェクトを追加する際のベスト プラクティスを見つけることです。私は両方の方法で行われた例を見てきました:

  1. (+ をクリックした後) テーブル ビュー コントローラーで新しい管理対象オブジェクトを作成し、その新しい輝く管理対象オブジェクトを下位の "追加" ビュー コントローラーに渡して、すべてのオブジェクト属性に対するユーザー入力を取得します。これは単純に見えますが、返されるオブジェクトには個々の属性がすべて含まれているため、簡単に理解できます。しかし、渡された管理対象オブジェクトを削除し、それ自体を閉じる前に Save Context を呼び出す「キャンセル」ボタンの「追加」ビュー コントローラのサンプル コードを見てきました。機能していますが、私の肩に乗っている MVC トレーニング gnome は、この従属ビューの追加でオブジェクトを削除し、恐怖が直接 Save Context を呼び出すことについて私に叫んでいます。Apple の Recipe サンプル コードは、このメソッドを使用しているようです。

  2. Add ビュー コントローラーには何も送信せず、デリゲート呼び出しをテーブル ビュー コントローラーに送り返します。このデリゲートは、各属性を個別の渡されたパラメーターとして返します。したがって、return メソッドは非常に長くなります: controller:(UIViewController *)controller didReturnFirstName:(NSString *)firstName andLastName:(NSString *)lastName andStreetAddress:(NSString *) and... and... and.. しかし、これは SO です管理対象オブジェクトは、すべての個別の属性を受け取るときにテーブル ビュー コントローラーに作成され、「追加」ビューはモデル (コア データ) に触れたり、ユーザーが変更したときに未使用の管理対象オブジェクトを破棄したりするため、MVC ドグマと一致します。彼らの心。
    チェーン化された委任されたメソッドでも、私はまだどちらがより良い方法であるかを自分自身と議論しています. 両方のフォームで生きてきた人からのコメントやアイデアは、歓迎すべき追加事項です.

ありがとう。

4

4 に答える 4

1

Apple のチュートリアルの例を見ると、以下に概説するいくつかのことを行うことでこのタスクを達成しています。この場合、データ モデルに追加する情報を入力するように見えるモーダル ビューがあります。

  1. 表示されるモーダルビューで、ビューを閉じるか、データを保存するかを処理するプロトコルと、そのプロトコルをデリゲートとして実装するタイプ id のプロパティを作成します。これにより、必要なメソッドを実装するオブジェクトが保証されます。

  2. モーダル ビューを作成したビュー コントローラーでは、データ モデルへのオブジェクトの保存やモーダル ビューの破棄など、プロトコルを実装します。

  3. モーダルを作成したビュー コントローラーで、モーダル ビューを作成したビュー コントローラーを、モーダルへのシーク中にモーダル ビュー デリゲートとして設定します。

要約すると、モーダル ビューで必要な新しいデータを収集するには: .h でプロトコルとプロパティを作成し、それを合成します。

 @protocol yourProtocol <NSObject>;
 //methods that determine what happens based on what user does, it would save your core data object
 @end

 @property(nonatomic, weak) id<yourProtocol> delegate;

次に、モーダル ビュー .m ファイルで、おそらく保存または完了を選択したときに、デリゲートでこれらのメソッドを呼び出します。そのため、おそらくボタンに接続された IBAction としてそれぞれのメソッド

 [self.delegate myMethod];

モーダル ビューを表示したビューでは、.h ファイルにプロトコルを実装します。

 @interface viewController() <yourProtocol>

最後に、モーダル ビューの .m ファイルを表示するビュー コントローラーにメソッドを追加します。これには、ビューの削除とコア データの保存が含まれます。Appleやその他の情報源によると、ポップアップ/モーダルなどを引き起こしたView Controllerは、それを却下するべきです。次に、seque indentfying を使用する seque で、モーダル ビューに表示されるビュー コントローラーをモーダル ビューのデリゲートとして設定します。

于 2012-05-01T22:28:46.187 に答える
1

そうです、これには多くのアプローチがあります。

保存されていない可能性のあるコンテキストから開始しているように聞こえるので、開始点に戻ることができるようにするために、次のように取り組みます。

  1. 「編集」ビューに渡される一時オブジェクトとして使用される新しい NSManagedObject を作成することから始めます。
  2. 既存のオブジェクトを編集している場合は、既存のオブジェクトからこの新しい一時オブジェクトに属性をコピーします (クイック for ループを使用して、それらをすべて一般的にコピーできます)。それ以外の場合は、新しく作成されたオブジェクトを続行します。
  3. 一時オブジェクトを「編集」ビュー コントローラーに渡し、両方のケースを同じように処理します。
    を。ユーザーがキャンセルを押した場合は、テーブルビューに通知するプロトコルまたはデリゲート メソッドを用意し、テーブルビューは単に一時オブジェクトを破棄します。
    b. 保存を押した場合は、テーブルビューに通知し、属性を一時コピーから元のオブジェクトにコピーし、一時オブジェクトを削除します (編集操作の場合)。 " 手術。
于 2012-05-01T23:19:48.867 に答える
0

NSManagedObjectContextAddController (新しいアイテムを作成する場合) または EditController (既存のアイテムを変更する場合) 用に新しいものを作成するのが正しいアプローチだと思います。

SDK に応じて、A) または B) を選択します。

A) 次に、そのコンテキストで変更を保存するか、コンテキストを破棄するかを選択できます。

「保存」の場合は、通知 ( ) を介して変更を TableController にマージできます。ManagedObjectContextNSManagedObjectDidSaveNotification

「キャンセル」の場合は、別のコンテキストを破棄できます。

B) または、OSX 10.7(+) を使用している場合は、ネストされた を使用して、AddController (子コンテキスト) にNSManagedObjectContextを作成NSManagedObjectContextし、その parentContext を TableController の に設定できますNSManagedObjectContext

「保存」の場合、子コンテキストと親コンテキストを保存します。

「キャンセル」の場合は、子コンテキストを破棄するだけです。

この詳細な例については、Apple の CoreDataBooks の例http://developer.apple.com/library/ios/#samplecode/CoreDataBooks/Introduction/Intro.htmlを参照してください。

于 2012-05-01T21:17:46.670 に答える
0

これは実際には答えではないので無視してかまいませんが、(これまでのところ) 他のどれも完全な答えではありません。新しい質問を作成せずにいくつかのポイントを追加する必要があると感じています。これも一番下。特に、答えは対処する必要があります

  • キャンセルと保存の違い
  • 新しいエンティティを作成するのではなく、既存のエンティティを編集するために同じコントローラーを使用したい場合はどうなりますか

ニックスの回答は、データを戻すためのアップルの(現在の)規則を扱っていますが、完全な回答ではありません.

しかし、この件に関しては、デリゲート規約が扱いにくい場合があることがわかり、より経験豊富な開発者からこれを読んで喜んでいます: http://robsprogramknowledge.blogspot.pt/2012/05/back-segues.html

ロブは、プロトコル/デリゲート規約(ニックの)、プロトコルなしのデータオブジェクトの使用(いわゆる「共有メモリ」)を含む、すべて等しく有効なさまざまなメカニズムについて詳しく説明しています-他の提案のいくつかのように、そして-私のお気に入り - ブロックを使用します。ブロックはデリゲートのように機能しますが、コードは「親」viewcontrollers ソースのコンテキスト内に完全に残るため、優れたオプションです。

ただし、「共有メモリ」の方が理にかなっています。なぜなら、あなたが言うように、これらすべてのプロパティを渡すために既に設計したデータ (マネージド) オブジェクト以外のものを使用するのはばかげているように思えるからです。

私にとっての問題は、これらの管理対象オブジェクトを作成し、それらを渡すための規則は何かということです.1.変更を保存する 2.変更をキャンセルする 3.新しいエンティティの作成を完全にキャンセルする

上記のInafzigersの回答はこのように機能しますが、なぜプロパティのコピーがすべて行われるのでしょうか? 変更を保存しないことはできませんか?

Apple の CoreDataBooks は、子ManagedObjectContext とそのコンテキスト (insertNewObjectForEntityForName) で、prepareForSegue とデリゲート メソッド (戻ってきたとき) に新しいエンティティを作成することで、これに対処しているようです。オブジェクトを格納するための ManagedObjectContext および親の FetchedResultsContext - Cancel がクリックされた場合、何もせず、新しい管理対象オブジェクト コンテキストを効果的に破棄するため、おそらく新しいオブジェクト

したがって、次の点を除いて、これは従来のアプローチである可能性があります。

  • そのサンプルのコード (CoreDataBooks RootViewController.m) には、2 つのマネージ コンテキストは必要ないというコメントがあり、1 つだけで同じことができる可能性があることを暗示しています。コメントの全文は次のとおりです。 重要: このために 2 番目のコンテキストを使用する必要はありません。既存のコンテキストを使用するだけで、コードの一部が簡素化されます。たとえば、2 つの保存を実行する必要はありません。ただし、この実装は、(別の編集セットを維持したい場合に) 役立つ場合があるパターンを示しています。

  • CoreDataBooks は UIManagedDocument を使用しません - それが違いを生むかどうかはわかりません

私には明確でないのは、insertNewObjectForEntityForName を使用して管理対象オブジェクトを作成する必要があるかということです。オブジェクトを作成し、後でユーザーが [保存] をクリックした場合にのみオブジェクトを挿入するのはどうでしょうか?

また、Edit と Cancel を行った場合はどうでしょうか。Undo Manager を使用して変更を取り消すことはできますか?

于 2012-09-26T18:50:51.270 に答える