7

次の一般的な状況を考慮してください。

MainViewによって制御されるNIBからロードされたCocoaアプリケーションにいくつかありますMainViewControllerMainViewには、などのいくつかのコントロールが含まれていますUILabel infoLabelMyDelegateまた、ある種のイベントを受け取るデリゲートクラスもあります。

MyDelegateイベントを受信したときに、infoLabelが適切に更新されていることを確認する必要があります。ただし、問題は、またはMyDelegateへの参照がなく、ラベルについて知らないことです。MainViewMainViewController

1つの解決策は、デリゲートオブジェクトへの参照を渡すMainViewControllerことですが、オブジェクトが互いの参照を持っているという望ましくない状況に陥る可能性があるため、これは間違っていると感じます。

この問題を解決するための適切な設計は何ですか?

4

4 に答える 4

4

名前のない開発者フォーラムで、誰かが次のように書いています。

それで、長い話を短くするために、私はNSNotificationsを利用し始めることにしました。人々がフォローしているオンラインのスタンフォードコースは、2人のアップルエンジニアによって教えられています。彼らは今、アプリデリゲートまたはグローバル変数を使用しないことを明確に述べており、NSNotifications、デリゲート、およびKV監視を使用すると述べています。

それがAppleのエンジニアの言うことなら、私はその方向に進むつもりです。

NSNotificationsは、カプセル化をそれほど妨げないという点で非常に独創的です。リスナーは通知とオブジェクトのみをリッスンします。誰が通知を送信したかを知る必要はないと思います。

したがって、あなたの例では、ラベルが変更されたという通知を代理人に投稿させるか、可能であればコントローラーにそのプロパティを監視させることを検討します。

于 2009-05-04T18:07:03.577 に答える
2

頭に浮かぶ2つのオプションは次のとおりです。

  • 委任するイベントがコントローラーによって送信される場合、そのメソッドにコントローラーに値を返して、ビューにプッシュさせることができます。

  • infoLabelの値をいくつかのキーにバインドすることもできます(たとえば、Cocoaバインディングまたは生のKey-Value Observingを使用して)。バインドされたオブジェクト(デリゲートまたは他のモデルオブジェクトである可能性があります)は、バインドされたキーを更新するだけで、infoLabelに値をプッシュできます。例として、デリゲートの「info」メンバーをinfoLabelの値にバインドできます。デリゲートがイベントを受信すると、情報メンバーを更新でき、ビューが変更されます。実際のバインディング自体は、IB(デリゲートがnibにある場合)またはコントローラー(ビューとデリゲートへの参照がある場合)で発生する可能性があります。

後者の解決策は基本的に循環参照ですが、私にはどういうわけかきれいに思えます。

于 2009-05-04T17:33:18.463 に答える
0

トリッキーな「データ」オブジェクトを実装しました。これは、ほとんどすべてを制御します。変更があるかどうかをチェックし、すべてのグローバルを最新の状態に保ちます。

新しいインスタンスを作成するときは、次のようにDataクラスを参照します。

[[Button alloc] initWithData:data]];

data単一のデータクラスはどこにありますか。これで、対応するために必要な変更があるかどうかを確認できます。

確かに、あなたが説明したように、それでも参照が必要です。parent埋め込まれた単純な参照はないようです。

于 2009-05-04T17:16:08.693 に答える
-1

通常のパターンは、あなたが言ったように、MainViewそのデリゲートメソッドを介してポインタを渡すことです。したがって、MainViewがデリゲートのdoSomethingWithFoo:メソッドを呼び出す場合は、そのメソッドを次のように変更します。

- (void)mainView:(MainView *)view doSomethingWithFoo:(id)foo

それに応じて新しいメソッドを呼び出します。MainViewポインターを直接操作する場合は、循環参照に問題はありません。

于 2009-05-04T17:12:47.077 に答える