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

时间:2015-01-23 00:15:52

标签: objective-c objective-c-blocks

假设我想在一个区块内执行@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)

1 个答案:

答案 0 :(得分:5)

简答:否

更长的答案:

背景

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

循环本身并不坏,只有当它导致循环中对象的生命周期延伸超过这些对象所需的点时,才会发生错误。只要周期被打破就可以创建一个循环 - 通过打破形成循环的一个链接 - 在某些时候。

类似的结构:

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

阻止创建静态循环(由self引用的对象强引用(引用的对象 - 你明白了,变量不重要但是东西)由它引用)blockVarblockVar只有弱引用回self

然而,每次执行块时,它都会创建一个强引用(存储在strongSelf中)到self,因此会创建一个动态循环 - 当它被自动打破时块完成执行。

您的代码

  1. 查看代码,创建一个块并将其直接传递给dispatch_async - 您永远不会在self中存储对该块的引用。所以这里永远不会有任何循环,根本不需要搞弱参考。

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

  3. HTH