The Timer strong reference
Assuming the VC has a timer running, if [self.timer invalidate] is not called; When we pop back the timer will still be executing and VC’s dealloc will not be called, so VC has no destructor
self.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:weakSelf selector:@selector(fireHome) userInfo:nil repeats:YES];
Copy the code
Why is timer not released? Please check the official document
//The object to which to send the message specified by aSelector when the timer fires. //The timer maintains a strong Reference to this object until it (the timer) is invalidated. // When timer fire is used, 'target' is strongly held until 'invalidated' is invokedCopy the code
At this time, there is a strong holding problem runloop -> timer -> self that is not the same as the block weakSelf can solve it, this time the model becomes runloop -> timer -> weakSelf -> self It didn’t work when it was tested without breaking the strong hold. So why is weakSelf added to the weak reference table, but is weakSelf the same as self? Verify first
9 (LLDB) p & Self (TimerViewController **) $0 = 0x0000000116B33FC8 (lldb) p &weakSelf (TimerViewController *const *) $1 = 0x00007ffee1ff2c08 (lldb)Copy the code
Turns out they’re different, just pointing to the same address. And the reference count doesn’t change. Does not break the strong holding relationship, so why can block, let’s take a look at the block source
void _Block_object_assign(void *destArg, const void *object, const int flags) { const void **dest = (const void **)destArg; switch (os_assumes(flags & BLOCK_ALL_COPY_DISPOSE_FLAGS)) { case BLOCK_FIELD_IS_OBJECT: /******* id object = ... ; [^{ object; } copy]; ********/ _Block_retain_object(object); Weakself (self) * object; break; default: break; }}Copy the code
const void **dest = (const void **)destArg; Weakself (pointer address of temporary variable) breaks the holding relation of this layer, while timer is the object of direct operation, so it cannot break the strong reference relation of this layer