如果dispatch_source_set_event_handler中的self需要弱

问题描述 投票:0回答:1

我有一个上传日志的计时器,代码如下:

- (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 代替吗?

objective-c grand-central-dispatch retain-cycle
1个回答
0
投票

tl;博士

是的,您引入了强引用循环。您应该使用

weakSelf
模式。


不用说,对于计时器,您只需在计时器代码中添加一些日志记录,这样您就会看到计时器在其所有者被解雇后仍在触发。

但更一般地说,为了确定对象在内存中保留的时间是否比预期的时间长,可以使用“调试内存图”功能凭经验验证这一点。

例如,在这里,我在视图控制器中启动了计时器,呈现并关闭了该视图控制器三次,内存图左侧的面板显示该视图控制器的三个实例仍在内存中!

有时,我们会很幸运,“内存图”会成功地将其识别为强引用循环(并且您可能会在主面板中看到⚠️警告图标或圆形图)。但是,有时,例如这里的情况,您只会看到挥之不去的实例,此时您可以开始寻找强引用循环(您已经在此处成功识别了它)。

在这种情况下,我:

  • 在我的方案设置下打开“Malloc Stack”诊断选项;
  • 在调试器中运行应用程序;
  • 体现了强引用循环;
  • 单击“调试内存图”按钮(上面屏幕快照底部圆圈所示);
  • 选择了挥之不去的视图控制器之一;
  • 单击保持强引用的对象;和
  • 然后我可以看到右侧的调用堆栈跟踪,然后单击代码中调用旁边的箭头(在上面屏幕快照的右边缘上圈出);和
  • 这把我带到了建立强参考的地方:

一旦定义了

weakSelf
并修改了块以调用
[weakSelf  sendLog]
,我就重复了上述步骤。不再有任何挥之不去的物体。

© www.soinside.com 2019 - 2024. All rights reserved.