3

これはばかげた質問かもしれませんが、MVC では、ビューはモデルを正しく認識していません。テーブル ビュー セルの例をいくつか見てきましたが、テーブル ビュー セルにはモデル オブジェクトのプロパティがあります。次に、そのモデルのプロパティを使用して、セルのラベルまたは画像を埋めます。

または別のケースでは、モデルに基づいて何かを動的に描画する UIView がある場合、UIView にプロパティを設定して、UIView がそのモデルのデータにアクセスして動的に描画できるようにするのが最も簡単なようです。だから私はこのようなことができます:

myView.object = newObject;
[myView setNeedsDisplay];

これはMVCにとって間違っていますか? もしそうなら、これら2つのことを行うためのより良い方法は何ですか? ありがとう。

4

3 に答える 3

4

MVC モデルにはさまざまなバリエーションがあります。Cocoa に関する Apple のドキュメントはこちらです: http://developer.apple.com/library/mac/documentation/General/Conceptual/CocoaEncyclopedia/Model-View-Controller/Model-View -Controller.html#//apple_ref/doc/uid/TP40010810-CH14-SW9 .

ここから得た主なことは、ビューをモデルに直接リンクしてはならないということです。次の図を参照してください。

Cocoa MVC パターンの Apple ダイアグラム

モデルUITableViewCellsオブジェクトのプロパティを持つことがよくありますが、これは間違っていると思います。パターンは次のようになります。

  • モデルは、実際のデータの保存と管理をすべて処理します
  • ビューは、表示されているデータのタイプを認識していますが、データ自体は認識していません。
  • コントローラー(UITableViewController) は、モデルからデータを取得してビューをセットアップする「接着剤」です。

これは実際にはどのように機能しますか?

次の疑似コードを直接入力しただけなので、いくつかの間違いをお許しください。テストはしていませんが、要点を示していることを願っています。

したがって、UITableViewCell次のようなサブクラスがあります。

@interface PhoneEntryTableViewCell {

@property (weak) IBOutlet UILabel *personName;
@property (weak) IBOutlet UILabel *phoneNumber;

}

モデルは次のようになります。

@interface PhoneModel {

@property (strong) NSMutableArray *listOfPeople;

}

そして、標準/メソッドをUITableViewController実装します。たとえば、次のようになります。UITableViewDelegateUITableViewDataSource

- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath {

  Person *person = [myModel personForIndex:indexPath.row];

  PhoneEntryTableViewCell *cell = [self dequeueReusableCellWithIdentifier:@"PhoneCell"];
  cell.personName.text = [person name];
  cell.phoneNumber.text = [person phoneNumber];

  return cell;
}

要約すると、Viewは実際のデータをまったく把握していません。ビューは、個人の名前と電話番号を表示する必要があることを認識しているだけです。バックエンド ストレージが何であるかを認識していません。コア データ、ファイル、ダウンロードおよび解析された JSON などである可能性があります。モデルについては何も認識していません。たとえば、モデルに関する他のデータを保存している可能性があります。人、たぶん電話番号は実際には名前とは別のモデルに保存されています。Controllerは、このすべての作業を処理します。

なぜこのようにするのですか?

したがって、上記のアプリケーションをロールアウトすると、Modelが非常に遅いことがわかります。 Viewに触れずに、完全に異なるモデルに交換できます。おそらく、別の開発者またはデザイナーにビューを作成してもらうことができます。彼らが知る必要があるのは、2 ビットのテキストを表示する必要があるということだけです。基本的に、コードをクリーンで明確に分割し、拡張しやすく、リファクタリングしやすくします。

ビューで次のようなことを行うとすぐにUITableViewCell、これらすべてがなくなります。

@property (strong) Person *person;
于 2012-07-26T19:41:54.783 に答える
0

まず第一に、「MVCモデル」はありません。それは微妙ですが重要な違いでさまざまな方法で概説されています。

ビュー内のコンポーネントが情報を取得する必要がある場合、2つの方法でこれを取得できます。それを要求する(ポーリング)か、通知を受ける(プッシュする)。ビューは実際にはモデルについて何も知らないため、通知はほとんどの場合、よりクリーンなアプローチである必要があります。これは、オブザーバーとして機能するだけです。

ただし、GUIコンポーネントは、例のように、データを保持し、データを要求できる「モデルオブジェクト」を必要とする傾向があります。モデルにちなんで名付けられることがよくありますが、アーキテクチャ的にはモデルに属する必要はありません。そして、私の意見では、モデルのインターフェースは事前定義されたGUIコンポーネントの必要性の後に構築され、MVCの全体的な意味がなくなったため、そうすべきではありません。モデルとビューを明確に分離したい場合は、次のようにしてみてください。

-----------------       -----------------       --------------      ---------
| GUI Component | --->  | "Model Class" | <-->  | Controller | ---> | Model |
-----------------       -----------------       --------------      ---------

したがって、GUIコンポーネントで期待される「モデルクラス」オブジェクトは、コントローラーのアダプターに他なりません。GUIとコントローラーの間のこの関係では、ポーリングまたはプッシュ(両側矢印の理由)など、好きな戦略を実装できます。

于 2012-07-26T18:55:06.853 に答える
0

または別のケースでは、モデルに基づいて何かを動的に描画する UIView がある場合、UIView にプロパティを設定して、UIView がそのモデルのデータにアクセスして動的に描画できるようにするのが最も簡単なようです。

では、正しい情報を取得するために、モデルに対してビューに何を伝えますか? 正しい質問をするためには、モデルについて何かを知っている必要がありますよね? または、 のようなプロトコルを定義して のようなUITableViewDataSource一般的なメッセージを送信-cellForRowAtIndexPath:し、そのプロトコルをモデルに実装することもできます。これにより、ビューがモデルに関する特定の情報を知る必要がなくなりますが、代わりに、モデルがビューについて知る必要があることを意味します。つまり、モデルが通過できるように、ビューに表示されるはずのものについて何かを知る必要があります。正しいデータを戻します。どちらの方法でも、モデルとビューの間に依存関係が生じます。つまり、一方を変更すると、もう一方も変更する必要があります。

この種の依存関係を回避することは、まさに MVC アーキテクチャのポイントです。コントローラーはモデルとビューの両方を認識しているため、モデルとビューを互いに独立して存在させることができます。

モデルとビューの両方が知っているいくつかのオブジェクトを持つことが理にかなっている場合があります。アドレス帳を作成している場合は、連絡先を表示する方法を知っている ContactView と、連絡先オブジェクトを格納するモデルを用意するのが理にかなっています。これは、表示内容について完全にばかげたビューを使用するよりもはるかに賢明に思えます。名前、住所、電話、ファックス、電子メールなどの長いリストの代わりに Contact オブジェクトを渡すことができます。Contact は、モデル オブジェクトであり、上記のすべてが適用されます。ContactView と Contact の間に依存関係を導入します。しかし通常、「モデル」について話すときは、プログラムがデータを格納するために使用するオブジェクトのグラフ全体を意味します。

于 2012-07-26T20:17:39.387 に答える