Difference between weak links in a block and NSTimer

As we know, we need to use a weak link inside the block to break the save loop like this:

__weak id weakSelf = self; [self doSomethingWithABlock:^() { [weakSelf doAnotherThing]; }] 

However, weak links cannot break the save cycle caused by a NSTimer .

 __weak id weakSelf = self; timer = [NSTimer scheduledTimerWithTimeInterval:30.0f target:weakSelf selector:@selector(tick) userInfo:nil repeats:YES]; // No luck 

Who cares? How can a timer save a target?

+5
source share
1 answer

The whole problem with the selector-based NSTimer method is that it sets up a strong reference to the object you pass to it. So, whether the variable that you used to bind to the target that you passed to scheduledTimerWithTimeInterval is unimportant, strong or weak. Assuming the target link was not nil by the time the scheduled selector-based timer was scheduled, NSTimer set its own strong link. The โ€œweakโ€ and โ€œstrongโ€ nature of the links in the calling code only dictates where the ARC will place its own memory management calls in the callerโ€™s code, but target is just a simple pointer, and not one of these weak and strong data is passed to NSTimer . The selector NSTimer will set its own strong link, which will not be resolved until the timer is invalidated .

That's why when we want to invalidate a timer created using a selector-based method, we should use it in viewDidDisappear or the like, not dealloc .

Note. scheduledTimerWithTimeInterval now has block-based variations for iOS 10 and later, so you can enjoy a weak reference block template if you don't need to support earlier versions of iOS:

 typeof(self) __weak weakSelf = self; [NSTimer scheduledTimerWithTimeInterval:30 repeats:true block:^(NSTimer * _Nonnull timer) { // use weakSelf here }]; 
+6
source

Source: https://habr.com/ru/post/1269541/


All Articles