0

我发现,当在ARC中使用NSNotificationCenter时,即使您忘记从defaultCenter中删除观察者,并且观察者已经释放,然后您发布观察者观察到的通知,不再有崩溃!NSNotificationCenter如何检测ARC中的释放观察者?

的Xcode 4之前,没有ARC,我们必须在dealloc的功能从默认通知中心删除观察者,像这样:

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

否则当一个绑定通知发布,它会通过靶向崩溃!

所以,问题是NSNotificationCenter如何检测ARC中的释放观察者?

+0

我的错,我没有发现任何坠毁因为观察者的另一个保留。 – Lings 2013-04-09 08:09:22

+0

这是NSNotificationCenter不保留观察者的证据。查看http://stackoverflow.com/questions/3964041/nsnotificationcenter-why-bother-calling-removeobserver – bluefloyd8 2013-12-29 23:53:00

回答

6

更新:从iOS 9和OS X 10.11开始,NSNotificationCenter观察者在解除分配时不再需要注销自己。 (来源:Unregistering NSNotificationCenter Observers in iOS 9


(旧答案:)即使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 
+0

我的错误,我发现没有崩溃,因为有另一个留守观察员。 – Lings 2013-04-09 08:10:01

+0

@灵魂:不客气! – 2013-04-09 08:19:30

+0

hm ...对我来说没有崩溃 – 2017-07-10 17:57:38

相关问题