11

私のアプリケーションには、HTTP を介したサーバーへの通信をカプセル化するオブジェクトがあります。このオブジェクトは、セッションが無効になった場合やユーザーへの新しいメッセージがある場合など、サーバーに変更があった場合に「ポーリング」する HTTP リクエストを作成します。

アプリケーションの UI オブジェクトは、UI オブジェクトが実装するプロトコルを介して通知を受信するために、自身を通信オブジェクトに登録する必要があります。登録は次のような方法で行われます。

[communicationObject addObserver: self];

そしてそれ自体を削除するには:

[communicationObject removeObserver: self];

通信オブジェクトは、可変配列にオブザーバーを格納します。場合によっては、UI オブジェクトは、UINavigationController にプッシュされた UIViewControllers です。その場合、ユーザーが親コントローラーに戻ると、通信オブジェクトのオブザーバー配列が UI コントローラーを保持するため、UI コントローラーは破棄されず、deallocメソッドが呼び出されないため、UI コントローラーはオブザーバーから自身を削除できません。 (明らかに)。

質問: このオブザーバー通知機能は悪いデザイン パターンですか? viewWillDisappearメソッドを使用せずに、UI コントローラーが親コントローラーによって解放されたことを検出する方法はありますか? この種の状況に対処するためのベスト プラクティスはありますか?

4

1 に答える 1

13

ベストプラクティス

オブザーバー パターンを使用していて、値が画面に表示されている間だけビュー コントローラーに値を監視させたい場合は、 addObserver:inviewDidAppearおよびremoveObserver:inを呼び出すことをお勧めしますviewWillDisappear。これは、これらのメソッドの設計や誤用ではありません。実際、これは標準的な方法であり、これらのビュー コントローラー メソッドの非常に良い使い方です。

値が画面から削除された後も、ビュー コントローラーで引き続き値を監視する必要がある場合は、まず、これが本当に必要なものであることを確認してください。その場合、覚えておくべきことがいくつかあります。

  • 特に、ビュー コントローラーが以前に存在し、新しく画面に表示された場合と同じ状態になるように、ビュー コントローラーが設定されていることを確認してください。これを行う適切な方法の 1 つ (そして通常、私自身のプロジェクトで行うこと) は、すべてのセットアップ コードをsetupメソッドに保持し、インスタンス化とプレゼンテーションの両方で同じように呼び出されるようにすることです。
  • また、バックグラウンドで高価な余分な計算が発生しないようにしてください。setup多くの場合、これは、オブジェクトの有効期間中一貫した状態を維持するのではなく、View Controller が表示されたときに呼び出されるメソッドに依存することで実現できます。
  • 最後に、View Controller が画面上にある場合、そのアウトレット (ビュー/サブビュー、まとめてビュー階層と呼ばれることが多い) のみが接続されることを忘れないでください。オフになっているが保持されている場合、これらはすべてnil. ビュー階層が準備できているかどうかを確認する良い方法は、isViewLoadedプロパティを使用することです。

リテンションとプレゼンテーション

ここで重要なのは、ビュー コントローラー (または、さらに言えば、任意のオブジェクト) がどこかに保持されているという考えと、それが画面上にあるという考えを混同しないことです。これらは非常に異なるイベントであり、多くの場合、一致しません。たとえば、UINavigationController1 つ以上の「子」View Controller を管理する「親」View Controller ( など) がある場合、複数の View Controller がインスタンス化されて一度に保持される可能性がありますが、画面には 1 つしか表示されません。時間。

さらに良い:NSNotificationCenter

必要に応じて、グローバル イベントを処理する別のオプションとして、 を介してオブザーバーを呼び出すようにNSNotificationCenter指定したりselector、通知を匿名で投稿したり、任意のイベント オブジェクト ( userInfo) を通知イベントに関連付けたりすることができます。このようにして、communicationObject通知を にポストし[NSNotificationCenter defaultCenter]、View Controller は で通知を観察しますdefaultCenter。同様の方法でオブザーバー オブジェクトを追加/削除することもできますが、グローバル イベントを調整する集中型のより堅牢な方法が得られます。

于 2013-01-09T17:51:02.420 に答える