0

ARC で使用している場合、 fromとhasNSNotificationCenterを削除するのを忘れても、オブザーバーが観察したという通知を投稿すると、もうクラッシュしないことがわかりました!!observerdefaultCenterobserverdeallocated

Xcode 4 より前では、ARC はありません。次のように、関数内のobserverデフォルトの通知センターからを削除する必要があります。dealloc

- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

そうしないと、バインドされた通知が投稿されると、クラッシュが発生します。

問題は、 ARCで割り当て解除されたものをどのようにNSNotificationCenter検出する かです。observer

4

1 に答える 1

6

更新: iOS 9 および OS X 10.11 の時点で、NSNotificationCenter オブザーバーが割り当て解除時に自身を登録解除する必要はなくなりました。(出典: iOS 9 での NSNotificationCenter オブザーバーの登録解除)


(古い回答:) ARC を使用しても、オブザーバーの割り当てが解除されると通知センターからオブザーバーを削除する必要があります。プログラムがクラッシュしなかったのは、まったくの偶然かもしれません。

次のプログラムはこれを示しています。「ゾンビオブジェクトを有効にする」オプションを有効にしました。

@interface MyObject : NSObject
@end

@implementation  MyObject

-(id)init
{
    self = [super init];
    if (self) {
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notify:) name:@"test" object:nil];
    }
    return self;
}
- (void)dealloc
{
    NSLog(@"dealloc");
    //[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)notify:(NSNotification *)notification
{
    NSLog(@"notify");
}

@end

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        MyObject *o = [[MyObject alloc] init];
        [[NSNotificationCenter defaultCenter] postNotificationName:@"test" object:nil];
        o = nil; // This causes the object to be deallocated
        // ... and this will crash
        [[NSNotificationCenter defaultCenter] postNotificationName:@"test" object:nil];
    }
    return 0;
}

出力:

notifytest[593:303] notify
notifytest[593:303] dealloc
notifytest[593:303] *** -[MyObject notify:]: message sent to deallocated instance 0x100114290
于 2013-04-09T08:00:39.430 に答える