繁体   English   中英

保留循环,强烈引用dispatch_queue

[英]Retain cycle with strong reference to dispatch_queue

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

@property (nonatomic, strong) dispatch_queue_t databaseQueue;

然后我执行这个线程的操作

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

这可能会创建保留周期吗?

当前类拥有对viewControllerToDismiss的强引用,并且有一个代码如下:

[viewControllerToDismiss dismissViewControllerAnimated:shouldAnimateDismiss completion:^{

   [self performSomeAction];
}

这是一个保留周期吗?

首先,您尚未声明一个主题 这是一个队列,这是不同的东西。 (幸运的是,直接使用线程是一件痛苦的事。)

您正在将一个块分派到队列中。 该块保留self并且队列保留块,这意味着您确实有一个保留周期,因为队列是一个strong属性,由self保留:

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

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

直接在块中使用self将创建强大的保留周期。

为避免保留周期,请检查以下代码

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

有关更多信息,请访问此链接使用块

它只是对self的强引用,当块完成运行并且GCD释放块时自动消除。 注意,这是队列对象本身,块和self之间的强引用,而不是databaseQueue 例如,即使在调度之后但在运行之前, databaseQueue是一些超出范围的本地引用,您仍然在队列对象,块和self之间有一个强引用。

如果您根本不想要强引用,请使用weakSelf模式:

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

您询问:

请你详细说明一下“注意,这是队列对象本身,块和自身之间的强引用,而不是databaseQueue”?

考虑:

- (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模式中获得任何东西(除了使代码更复杂)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM