2016-09-23 6 views
1

Почему этот блок завершения правильно вызван?Почему этот блок завершения правильно вызывается?

CompletionBlock comp = ^(BOOL enabled) { 
      //enabled is being correctly set 
      NSLog(@"result: %i", enabled); 
}; 

@autoreleasepool { 
    Monitor *monitor = [[Monitor alloc]initWithCompletionBlock:comp]; 
    monitor = nil; 
} 

Монитор запустит NSTimer, чтобы вызвать блок завершения через 10 секунд после создания экземпляра монитора.

Монитор действительно имеет ссылку на comp внутри (в порядке @property (nonatomic) CompletionBlock compblock;), но ингредиенты для круглой ссылки, похоже, отсутствуют, так как ничто не ссылается на монитор.

Это нормальное поведение? И это поведение, на которое я могу рассчитывать? Это действительно не имеет смысла для меня.

+0

Не видя реализации класса Monitor, мы не можем дать вам правильный ответ. – rmaddy

ответ

2

Предположительно, цель Monitor является целью. NSTimer сохраняет свою цель во избежание сбоя, вызванного сообщением освобожденного объекта при его возникновении. * В текущем цикле выполнения сохраняется таймер, когда он запланирован.

Это нормальное поведение, и you can rely on it:

цель
Объект, к которому следует отправить сообщение [...] Таймер поддерживает сильную ссылку на target ...

Фактически, вы должны принять это во внимание, чтобы не создавать цикл сохранения между таймером и его целью.


* NSTimer предшествует авто-nilling слабые ссылки на долгое время.

+0

Вы правы, объект Monitor является целью. Я также использую повтор: НЕТ. В документации указано, что после срабатывания таймера он будет признан недействительным. Я предполагаю, что это означает, что после завершения селектора? В противном случае будет шанс, что GC сможет это сделать слишком рано. – user3564870

+1

Да, таймер не будет аннулировать себя до тех пор, пока он не сообщит своей цели о выполнении селектора. –