块中的@synchronized(self) 是否会导致保留周期?

Does @synchronized(self) in a block lead to a retain cycle?

假设我想在一个块内执行 @synchronized(self)。我想这会导致一个保留周期,所以通常我们会这样重写它:

-(void)myMethod
{
    __weak TheClass * weakSelf = self;
    dispatch_async(dispatch_get_main_queue(),
    ^{
        TheClass * strongSelf = weakSelf;
        if(strongSelf == nil)
        {
            return;
        }

        @synchronized(strongSelf)
        {
            //mutex code
        }
    }
}

我的问题是,当您以这种方式使用 @synchronized 指令时,它是否等同于 @synchronized(self)

简答:否

更长的答案:

背景

要有一个涉及块的循环,该块必须引用另一个对象,并且该对象必须(直接或通过更长的链)引用该块。

一个循环本身并不坏,只有当它导致循环中对象的生命周期延长到超过需要这些对象的时间点时才是坏的。可以创建一个循环,只要循环被打破——通过打破形成循环的链接之一——在某个时刻。

构造如:

__weak TheClass * weakSelf = self;
...
self.blockVar = ^{
    TheClass * strongSelf = weakSelf;
    ...

防止 static 循环被创建为(被引用的对象)self 强引用(被引用的对象 - 你明白了,变量不是'不重要,但被它引用的东西)blockVarblockVarself.

的引用很弱

然而,每次执行该块时,它都会创建一个对 self 的强引用(存储在 strongSelf 中),因此会创建一个 dynamic 循环 - 这当块完成执行时自动中断。

您的代码

  1. 看看你的代码,你创建了一个块并将其直接传递给 dispatch_async - 你从未在 self 中存储对该块的引用。所以这里从来没有任何循环,根本不需要弄乱弱引用。

  2. 一旦块创建 strongSelf 有一个循环,然后使用 @synchronized(strongSelf) 不会创建第二个,它只是锁定对象。 synchronized 语句退出时,锁进入,块退出时,强循环进入。

HTH