保留周期,有力地参考dispatch_queue



在类中,我已经声明了一个线程:

@property (nonatomic, strong) dispatch_queue_t databaseQueue;

然后我执行此线程,例如

dispatch_async(self.databaseQueue, ^{
        [self.dao deleteRetries];
    });

这可能会产生保留周期?

当前类对viewControllerToDismiss有很强的引用,并且有一个看起来像:

的代码
[viewControllerToDismiss dismissViewControllerAnimated:shouldAnimateDismiss completion:^{
   [self performSomeAction];
}

这是保留周期吗?

它只是对self的强有力参考,当块完成运行并释放块时,它会自动消除。注意,这是队列对象本身,块和self之间的强有力参考,但不是databaseQueue。例如。即使 databaseQueue是派遣后但在运行之前脱离范围的某些本地参考,您仍然在队列对象,块和 self之间有很强的参考。

如果您根本不想要强有力的参考,请使用weakSelf模式:

typeof(self) __weak weakSelf = self;
dispatch_async(self.databaseQueue, ^{
    [weakSelf.dao deleteRetries];
});

您问:

请您更多地详细说明"注意,这是队列对象本身,块和自我之间的强有力参考,但不是对数据库形式"?

考虑:

- (void)runManyTasks {
    dispatch_queue_t queue = dispatch_queue_create("com.domain.app.foo", 0);
    for (NSInteger i = 0; i < 10; i++) {
        dispatch_async(queue, ^{
            [self doSomething];
        });
    }
}
- (void)doSomething {
    [NSThread sleepForTimeInterval:1];
}

即使我的代码中没有引用该本地变量queuerunManyTasks完成后,如果我致电runManyTasks,GCD仍将保持其自己的强有力的参考,直到所有任务完成为止,并且排队将使排队将保留这些块的副本,直到完成运行为止,这些块将保持对self的强烈参考,直到GCD使用所有块(大约10秒,在此示例中)。


您继续编辑您的问题并询问:

当前类对viewControllerToDismiss有很强的引用,并且有一个看起来像:

的代码
[viewControllerToDismiss dismissViewControllerAnimated:shouldAnimateDismiss completion:^{
     [self performSomeAction];
 }

这是保留周期吗?

对于所有实际考虑,没有。该块一旦完成,就会释放该块,因此您通常不会在此处使用weakSelf模式使您的代码复杂化。实际上,无论如何,直到动画完成之前,该视图控制器才被解雇,因此weakSelf模式绝对没有任何收益(除了使代码更复杂)。

首先,您尚未声明 thread 。这是队列,这是不同的。(幸运的是,由于直接使用线程是一种痛苦。)

您将块派遣到队列。该块保留self,队列保留该块,这意味着您 do 具有保留周期,因为队列是strong属性,由self保留:

self -> queue -> block -> self -> queue -> …

但是,从API来看,该区块应该是短暂的。块完成后,它将从队列中释放出来,打破保留周期。所以我不必担心这样的情况。

直接在块中使用自我会产生强保留周期。

要避免保留周期,请检查下面的代码

__weak YourViewController *weakSelf = self;
dispatch_async(self.databaseQueue, ^{
     if (weakSelf){
        YourViewController *strongSelf = weakSelf;
        [strongSelf.dao deleteRetries];
      }
    });

有关更多信息,请访问此链接与块一起工作

最新更新