我有一个上传日志的计时器,代码如下:
- (void)setupTimer {
if (_timerForRecording) {
dispatch_source_cancel(_timerForRecording);
_timerForRecording = NULL;
}
_timerForRecording = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, _safeTransactionQueue);
if (_timerForRecording) {
dispatch_source_set_timer(_timerForRecording, dispatch_time(DISPATCH_TIME_NOW, 4.5 * NSEC_PER_SEC), 4.5 * NSEC_PER_SEC, 0.5 * NSEC_PER_SEC);
dispatch_source_set_event_handler(_timerForRecording, ^{
[self sendLog];
});
dispatch_resume(_timerForRecording);
}
}
看起来使用 self 不会导致保留周期,我应该使用weakSelf 代替吗?
tl;博士
是的,您引入了强引用循环。您应该使用
weakSelf
模式。
不用说,对于计时器,您只需在计时器代码中添加一些日志记录,这样您就会看到计时器在其所有者被解雇后仍在触发。
但更一般地说,为了确定对象在内存中保留的时间是否比预期的时间长,可以使用“调试内存图”功能凭经验验证这一点。
例如,在这里,我在视图控制器中启动了计时器,呈现并关闭了该视图控制器三次,内存图左侧的面板显示该视图控制器的三个实例仍在内存中!
有时,我们会很幸运,“内存图”会成功地将其识别为强引用循环(并且您可能会在主面板中看到⚠️警告图标或圆形图)。但是,有时,例如这里的情况,您只会看到挥之不去的实例,此时您可以开始寻找强引用循环(您已经在此处成功识别了它)。
在这种情况下,我:
一旦定义了
weakSelf
并修改了块以调用 [weakSelf sendLog]
,我就重复了上述步骤。不再有任何挥之不去的物体。