块中的弱引用与NSTimer之间的差异

时间:2017-07-06 03:36:00

标签: ios objective-c objective-c-blocks nstimer

正如我们所知,我们需要在块内使用弱引用来打破保留周期,如下所示:

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

然而,弱引用不能破坏由NSTimer引起的保留周期。

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

区别是什么?计时器如何仍然保留目标?

1 个答案:

答案 0 :(得分:6)

基于选择器的NSTimer技术的整个问题是它建立了对传递给它的对象的强引用。因此,用于保存对传递给scheduledTimerWithTimeInterval的目标的引用的变量本身是强还是弱,是无关紧要的。假设target引用在计划基于选择器的计划计时器时没有nilNSTimer将建立自己的强引用。 "弱" vs" strong"调用代码中引用的性质仅指示ARC将在调用者代码中放置自己的内存管理调用的位置,但target只是一个简单的指针,并且这些弱信息和强信息都不会被传达到NSTimer。基于选择器的NSTimer将建立自己的强引用,直到计时器为invalidated才会解析。

这就是为什么当我们想要使通过基于选择器的方法构建的计时器无效时,我们必须在viewDidDisappear之内,而不是dealloc

注意,scheduledTimerWithTimeInterval现在有一个基于块的iOS 10及更高版本的变体,所以如果你不必支持早期的iOS版本,你可以享受块的弱参考模式:

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