2012-05-17 7 views
19

addObserverviewDidLoad:に、removeObserverdealloc:に使用しました。コード:NSNotificationCenterを使ってaddObserver/removeObserverを追加するより良い方法はありますか?

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    [[NSNotificationCenter defaultCenter] addObserver:self 
              selector:@selector(refreshData) 
               name:AnyNotification 
               object:nil]; 
} 

- (void)dealloc 
{ 
    [[NSNotificationCenter defaultCenter] removeObserver:self 
                name:AnyNotification 
                object:nil]; 
} 

しかし、いくつかの記事によると、それがviewDidDisappear:viewDidAppear:removeObserveraddObserverすると良いでしょう、と述べました。コード:

- (void)viewDidAppear:(BOOL)animated 
{ 
    [super viewDidAppear:animated]; 

    [[NSNotificationCenter defaultCenter] addObserver:self 
              selector:@selector(refreshData) 
               name:AnyNotification 
               object:nil]; 
} 

- (void)viewDidDisappear:(BOOL)animated 
{ 
    [super viewDidDisappear:animated]; 

    [[NSNotificationCenter defaultCenter] removeObserver:self 
                name:AnyNotification 
                object:nil]; 
} 

これで、addObserver/removeObserverはどのような方法で追加できますか?

+0

メモリ警告が発生する可能性がある場合は、オブザーバを 'dealloc'で削除するのは良いことではありません。 – Eimantas

+1

ビューが消えてしまったので、removeObserverではなく、それぞれの特定の通知に対してオブザーバを削除してください:自分自身を削除するか、ビューが再表示されたときにスーパークラスの通知オブザーバを削除します。 – chourobin

答えて

19

これはあなたのシナリオに依存し、通常、最善のアプローチはviewDidLoadに追加し、deallocにし、viewDidUnloadで削除することですが、あなたはUIエフェクトなどの異なるクラスで同じメソッドを持っているだけで、現在の画面のを呼び出したいとき、いくつかの例がありますすべてのケースでは、私が出会ったので、通知を使用する方法は、あなたは単にviewWillAppearにオブザーバを追加し、私は通常-viewDidAppear:-viewDidDisapear:(または-viewWillAppear:-viewWillDisappear:)に入れてしまうviewWillDisappearまたはviewDidAppear/viewDidDisappear

+6

クラスが挿入されているがビューがロードされていない状況がある可能性があるため、最初の解決策はベストではないと思います。アプリケーションがエラーでクラッシュする "オブザーバとして登録されていないため、からキーパス" KEY_PATH "のオブザーバを削除できません。 – DanSkeel

+2

@DanSkeelは 'init'と' awakeFormNib'を追加することができますか? – Puttin

+0

なぜ 'viewWillAppear'ではなく、' viewDidLoad'を追加するのがベストですか?私は利益を見ません。私はそれが必要なときだけオブザーバーを周りに保つのが好きなので、私は 'viewWillAppear'と' viewWillDisappear'を使います。また、これらの呼び出しは確実にペアになっているようです。 – ToolmakerSteve

3

でそれを削除する必要があります私は通知に興味があるのは、vi ewが実際に表示されます。

これはおそらく時期尚早の最適化です(通知を処理するコードには時間がかかるかもしれませんが、表示が表示されない場合は役に立たないかもしれません)が、それ以上のコードではありません。 ...

1

NSKeyValueObservingOptionInitialを忘れないでください。私はviewWillAppear/viewWillDisappearでそれを使用するので、UIが常に最新の状態になります。ビューコントローラを非表示にしてもリソースを保存しても、更新されないため、再度表示されません。

0

-viewWillAppear: + -viewWillDisappear:は、常に同じ回数と呼ばれるので、-viewDidAppear: + -viewDidDisapear:よりも優れています。

+0

@ToolmakerSteve、ペアになっています。 – 0xa6a

+0

@ToolmakerSteve、ナビゲーションコントローラの 'interactivePopGestureRecognizer'が有効なとき。 – 0xa6a

+0

OK、あなたが今言っていることを理解しています。私はあなたの言葉を編集して、あなたが重要なことをしていると信じているように、それをもっと明確にし、あなたを上向きにしました。 [私は現在、アプリケーションを開発していないが、そのため、機能が常にバランスしているかどうかを確認することはできません。](誰かがあなたを落としてしまったのでしょうか、おそらく私が混乱したのと同じ理由で - あなたが言っていたこと。) – ToolmakerSteve

0

NSNotificationsを使用して最善のアプローチは、あなたはもうそれらを必要としないときにそれらを削除し、通知とのために観察する必要があるときにオブザーバーを追加です。

これはviewDidLoad:viewWillAppear:、またはユーザーがいくつかのボタンをタップするなど

上に置くことができ、私はあなたに少しの例を与える:私のアプリはタブバーを持って

、およびビューコントローラの一部で私はインターネットからダウンロードした情報を表示しています(例えば、つぶやき)。私はまた、2分ごとにサーバーから新しいデータをプールするクラスを持っていて、サーバーに新しいデータがあるので、データベースに関する情報を更新しました。私は非常に多くのビューコントローラにデータを表示しているので、デリゲートのパターンを使用しないでください。デリゲートを配列にして、すべてのビューコントローラのデータを渡すループが非常に悪いデザインになります。この特定のシナリオでは、新しいデータが来たことをすべてのVCに伝える通知を送信するのが最善の方法です。

ビューが表示されなくなったときにVCがデリゲートを削除した場合、現在のビューのみが通知を受け取り、表示内容を更新します。

表示する前に、他のVCの内容を表示する前に、たとえばviewWillAppear:に変更することはできますが、これを行うと、必要に応じてVCの内容が更新されます。

これは、NSNotificationsの場合、アプリケーション動作の説明の全体がわからないときにオブザーバーを追加または削除するときにアドバイスするのは難しいことを示したところです。

関連する問題