NSNotificationCenter如何检测ARC中的解除分配的观察者?

Lin*_*ngs 0 objective-c nsnotificationcenter automatic-ref-counting

我发现NSNotificationCenter在ARC中使用时,即使你忘记删除了observerfrom defaultCenterobserverhas deallocated,然后你发布了观察者观察到的通知,也没有崩溃了!

在Xcode 4之前,没有ARC,我们必须observerdealloc功能中删除默认通知中心,如下所示:

- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}
Run Code Online (Sandbox Code Playgroud)

否则当发布绑定通知时,它会发生崩溃!

所以,问题是如何在NSNotificationCenter检测解除了分配observerARC

Mar*_*n R 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;
}
Run Code Online (Sandbox Code Playgroud)

输出:

notifytest[593:303] notify
notifytest[593:303] dealloc
notifytest[593:303] *** -[MyObject notify:]: message sent to deallocated instance 0x100114290
Run Code Online (Sandbox Code Playgroud)