假设我要在一个区块内执行@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)
?
简短的回答:否
更长的答案:
背景
要有一个涉及一个块的cycle,该块必须引用另一个对象,并且该对象必须(直接或通过更长的链)引用该块。
循环本身并不坏,仅当它导致循环中对象的生存期延长到需要这些对象的时间点时,这才是不好的。只要在某个时候断开循环(通过断开形成循环的链接之一),就可以创建一个循环。
类似的构造:
__weak TheClass * weakSelf = self;
...
self.blockVar = ^{
TheClass * strongSelf = weakSelf;
...
防止static循环被创建为(被self
引用的对象)强引用(被-C引用的对象-您知道,变量并不重要,但被它引用的事物)[ C0],但blockVar
仅具有弱引用回到blockVar
。
但是每次执行该块时,它都会为self
创建一个强引用(存储在strongSelf
中,因此会创建一个dynamic循环-当该块完成执行时会自动中断。
您的代码
查看您的代码,创建一个块并将其直接传递给self
-您从不将对该块的引用存储在dispatch_async
中。因此,这里从来没有任何循环,根本不需要弄乱弱引用。
一旦块创建了self
,就会有一个循环,然后使用strongSelf
不会创建第二个循环,它只是对对象进行了锁定。当同步语句退出时,锁消失,当块退出时,强循环消失。
HTH