0

Я обнаружил, что при использовании NSNotificationCenter в ARC даже вы забываете удалить наблюдателя из центра по умолчанию, а наблюдатель освобожден, после чего вы публикуете уведомление, наблюдаемое наблюдателем, больше нет сбоев !!Как NSNotificationCenter обнаруживает освобожденного наблюдателя в ARC?

перед тем Xcode 4, нет ARC, мы должны удалить наблюдатель от центра уведомлений по умолчанию в функции dealloc, как это:

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

в противном случае, когда переплетено уведомление отправлено, оно будет Тригером краха!

так, вопрос в том, как NSNotificationCenter обнаруживает освобожденного наблюдателя в ARC?

+0

моя ошибка, я не нашел аварии, потому что есть другой сохранить наблюдателя. – Lings

+0

Это свидетельствует о том, что NSNotificationCenter не сохраняет наблюдателей. См. Http://stackoverflow.com/questions/3964041/nsnotificationcenter-why-bother-calling-removeobserver – bluefloyd8

ответ

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

+0

@Lings: Добро пожаловать! –

+0

hm ... no crash for me –

Смежные вопросы