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



假设我想在一个块内做@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;
    ...

防止将静态循环创建为(引用的对象)self强引用(引用的对象 - 你明白了,变量并不重要,但被它引用的东西)blockVarblockVar只有一个弱引用回self

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

您的代码

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

  2. 一旦块创建了strongSelf就会有一个循环,那么使用 @synchronized(strongSelf) 不会创建第二个循环,它只是锁定对象。当同步语句退出时,锁消失,当块退出时,强循环消失。

相关内容

  • 没有找到相关文章

最新更新