在类中,我已经声明了一个线程:
@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];
}
即使我的代码中没有引用该本地变量queue
,runManyTasks
完成后,如果我致电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];
}
});
有关更多信息,请访问此链接与块一起工作