4

このカテゴリの方法は、NSNotificationCenterオブザーバーの追加保持を避けることができますか?NSNotificationCenterの保持サイクルを避けますか?

#import "NSNotificationCenter+Util.h" 

@implementation NSNotificationCenter (Util) 

- (void)addWeakObserver:(nonnull NSObject*)observer selector:(nonnull SEL)aSelector name:(nullable NSString *)aName object:(nullable id)anObject { 
    __weak NSObject *weakObserver = observer; 
    [self addObserver:weakObserver selector:aSelector name:aName object:anObject]; 
} 

@end 

目標は、オブジェクトを削除せずに死ぬことです。


注:私はサイクルを維持する原因とこの問題を回避しようとしている

notificationObserverまたは addObserver:selector:name:object:に指定されたオブジェクトが割り当て解除される前removeObserver:name:object:を起動してください。

答えて

4

ません - weakObserverweakとなりますので、割り当て解除、しかしaddObserver:...はオブザーバを保持している場合、それはオブザーバーを保持し、自動的にnilobserver場合されます。オブジェクトには、以前のリファレンスがそれを保持していた方法についての歴史はありません。それは、それ自身の動作を制御するリファレンスそのものです。

ただし、NSNotificationCenterはオブザーバーを保持せず、オブザーバーはほとんど通知センターを保持しません。保持サイクルはありません。あなたが多かれ少なかれ引用したテキストは、通知センターに格納されているポインタがぶら下がり、つまり所有権を主張していないことを示しています。

これまでに行ったことは、センター内に参照を自動的に保存することはありません。nil

iOS 9およびOS X v10.11以降、この動作はis already fixedです。弱参照は、弱く参照できるすべてのオブジェクトに対して通知センタによって使用されます。

+0

ありがとう、私は間違ってそれを読んでいたことに気付かなかった。しかし、もっと重要なことに、私は知らなかった。「以前の参考文献がそれを保持してきた方法に関しては、オブジェクトに歴史はなく、それは自分自身の行動を制御する参照そのものだ」魅力的な –

5

NSNotificationCenterobserverを保持しないため、addObserver:selector:name:object:だけを使用して保持サイクルを作成することはありません。そのためにラッパーメソッドは必要ありません。

あなたからobserverを削除するために失敗した場合NSNotificationCenterは、これらのバージョンより前のオペレーティングシステムではOS X 10.11(エル・キャピタン)とiOS 9までの弱参照をゼロに使用していなかったので、removeObserver:name:object:の呼び出しについて警告する理由は、 observerの割り当てを解除すると、通知センターはobserverに通知を送信しようとし続けます。これは一般的にクラッシュを引き起こすか、悪化させるでしょう。

デプロイメントターゲットがOS X 10.11またはiOS 9以上であれば、割り当て解除時にobserverを削除することを心配する必要はありません。

-[NSNotificationCenter -addObserverForName:object:queue:usingBlock:]を使用している場合は、あなたのオブザーバーを強く保持しているブロックに起因する保持サイクルを避けることを心配する必要があります。

+0

ありがとう、これはちょうど私がスウィフトの遊び場で私の頭を傷つけていたものです:実際には何も起こっていません!これは素晴らしく、非常に有益です。もう一度感謝します。 –

関連する問題