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

问题描述 投票:1回答:1

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

objective-c memory-management objective-c-blocks synchronized reference-cycle
1个回答
6
投票

简短的回答:否

更长的答案:

背景

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

循环本身并不坏,仅当它导致循环中对象的生存期延长到需要这些对象的时间点时,这才是不好的。只要在某个时候断开循环(通过断开形成循环的链接之一),就可以创建一个循环。

类似的构造:

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

防止static循环被创建为(被self引用的对象)强引用(被-C引用的对象-您知道,变量并不重要,但被它引用的事物)[ C0],但blockVar仅具有弱引用回到blockVar

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

您的代码

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

  2. 一旦块创建了self,就会有一个循环,然后使用strongSelf不会创建第二个循环,它只是对对象进行了锁定。当同步语句退出时,锁消失,当块退出时,强循环消失。

HTH

© www.soinside.com 2019 - 2024. All rights reserved.