2012-01-18 3 views
4

私はMacプログラミングには新しく、ドキュメントベースのアプリケーションで作業しています。文書ベースのCocoaアプリケーションでの結合を回避するには?

私のNSDocumentサブクラスはNSWindowControllerサブクラスを作成します。このウィンドウコントローラは、サブクラスとしても2つのNSViewControllerサブクラスを作成します。

時々、NSViewControllerのビューの1つを変更すると、NSDocumentおよび/またはメインモデルクラスに通知する必要があります。また、モデルの変更は、すべての/一部のビューに通知する必要があります。

私の質問は、カップリングがない(または最小限の)カップリングがないのは何ですか?私はいくつかの選択肢があるけど、私は、私は、プログラミングではなくNSDocumentココアにし、特に初心者じゃないと自分のアプリケーションのための最高のスーツたかわからないんだけど:

  • KVO。いいえ、実装が簡単ですが、私は明示的にオブザーバに変更(AFAIK、self.someProperty = newValueは自動的にオブザーバに通知する)を通知しないという考え方は嫌いです。登録しなければならないという事実は気に入らない時間が経つにつれて変化する可能性のあるプロパティ名に変換します。

  • 通知。私は彼らが何であるかを知っていて、私はそれらをiOSのために使いました。しかし、私はどこかで、彼らがただちにオブザーバーに送られることは保証されていないと読んだ。本当ですか?そうでない場合は、ドキュメントベースのアプリの優れたアプローチと見なしますか?

  • 代表者。はい、通常の状況(または私が通常見たことがある)では、クラスには1つのデリゲートがあります。しかし、デリゲートの配列を作成するだけでも動作します(テスト済みです)。私がここで見る問題は、デリゲートに通知する必要があるたびに、ループを繰り返す必要があり、メソッドに応答することを確認し、そのメソッドを呼び出すことです。

他にも選択肢がありますか?

+0

通知*はただちにオブザーバーに送付されます。 –

答えて

1

コントローラクラスによるKVOは、モデルとそのビューの結合を行う最も一般的な方法です。実際、コントローラーレイヤーでコードをほとんど除去することを意図したCocoa Bindingsは、KVOに基づいています。 KVO/KVCはプロパティ名に依存しており、これらが変更された場合、ビューを結ぶバインディングやKVOの設定を変更する必要があります。しかし、基本的なモデルの詳細をあなたの見解に完全に気づかせるのは通常実現できません。だから私はこれを問題として見ません。

私は、できるだけ多くのグルーコードを排除するので、できる限りココアバインディングを使用することをお勧めします。それらが使用できない場所では、コントローラ(MVCの中間層)はKVOを使用してモデルの変更を観察し、適切なビューを更新する必要があります。ビューの変更は、コントローラによってプロパティアクセサーおよび/またはKVCを介してモデルに戻すことができます。

+1

私は、モデルを完全に認識できないという意見には同意できません。それが真実であれば、 'NSTableView'は事実上すべてのCocoa開発者のために働くことができませんでした。利用可能なパターン(バインディング、デリゲート、データソース)を使用すると、ビューを完全に独立させることができます。実際は、これが目標です。 –

+0

はい、そうです。ビューはモデルを認識できませんが、コントローラレイヤーはモデルとビューの両方の詳細を知る必要があります。 OPは実際にコントローラレイヤー(NSViewControllerとNSWindowControllers)について質問しています。 NSTableView自体はモデルには依存しませんが、モデルに接続するために使用されるコントローラはモデルの詳細を知る必要があるため、コントローラクラスにハードコードされたキーパスを持つことは悪くありません。 –

+0

@AndrewMadsenありがとうございます。私が明示的に_willChangeValueForKey_と_didChangeValueForKey_を呼び出す必要がある場合を除いて、KVOに切り替えてクリーナーコードに気づいただけです。これらのメソッドを呼び出さないと、オブザーバーは変更を気付かなかったからです。再び、私はKVOをかなり新しくしています。クラスがKVC準拠でなければならないことは知っていますが、これはオブザーバーに通知するものでも通知もしません。まだいくつかの知識が必要ですね。 – msoler

1

はい、通常の状況(通常は私が見たことがある)では、クラスには 代理人が1人あります。しかし、デリゲートの配列を作成するだけでも動作します( でテスト済み)。

デリゲートは、委任オブジェクトの動作を変更するためによく使用されます。アプリケーションデリゲートは良い例です:それ自体でNSApplicationはあまり面白くありません。デリゲートはアプリケーションの興味深い動作を定義することに依存しています。複数のデリゲートを持つことにより、複数のデリゲートが互いに競合すると、単一のオブジェクトの動作を変更しようとすると問題が発生する可能性があります。代議員が同意しない場合はどうしますか?

Cocoaでは、クラスが複数のデリゲートを使用するケースがありますが、それぞれには別々の役割があります。たとえば、NSTableViewにはデリゲートとデータソースの両方がありますが、どちらも実際にソートのデリゲートです。

私はここを参照してください問題は、私はそれらを介してループに私が持っている 代表者に通知する必要があるたびに、彼らは 法への対応、およびそのメソッドを呼び出して作るということです。

これは解決しにくいです。たとえば、NSInvocationを作成して呼び出しをカプセル化し、呼び出しを各「代理人」に送信できます。しかし、これを行うと、通知システムがほぼ再構築されます。複数のデリゲートプロポーザルで得られる1対多のコミュニケーションが必要な場合は、おそらく通知やKVOを使用する方がよいでしょう。

+0

はい、ほとんどの場合、1対多の通信が必要です。委任はちょっと混乱し始めました。皆さんが私がKVOに移ったことをお伝えしており、それはかなりうまく機能しています。ありがとう! – msoler

関連する問題