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

yan*_*ano 1 memory-management objective-c synchronized objective-c-blocks reference-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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

CRD*_*CRD 6

简答:不

更长的回答:

背景

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

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

像这样的构造:

__weak TheClass * weakSelf = self;
...
self.blockVar = ^{
    TheClass * strongSelf = weakSelf;
    ...
Run Code Online (Sandbox Code Playgroud)

防止创建一个静态循环(被引用的对象)self强引用(引用的对象 - 你得到的想法,变量不重要,但它被引用的东西),blockVarblockVar只有一个弱引用self.

但是,每次执行块时,它都会创建一个强引用(存储在strongSelf)中self,因此会创建一个动态循环 - 当块完成执行时会自动中断.

你的代码

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

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

HTH