假设我想在一个区块内执行@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)
?
答案 0 :(得分:5)
简答:否
更长的答案:
背景
对于涉及块的循环,块必须引用另一个对象,并且该对象必须(直接或通过较长链)引用该块。
循环本身并不坏,只有当它导致循环中对象的生命周期延伸超过这些对象所需的点时,才会发生错误。只要周期被打破就可以创建一个循环 - 通过打破形成循环的一个链接 - 在某些时候。
类似的结构:
__weak TheClass * weakSelf = self;
...
self.blockVar = ^{
TheClass * strongSelf = weakSelf;
...
阻止创建静态循环(由self
引用的对象强引用(引用的对象 - 你明白了,变量不重要但是东西)由它引用)blockVar
但blockVar
只有弱引用回self
。
然而,每次执行块时,它都会创建一个强引用(存储在strongSelf
中)到self
,因此会创建一个动态循环 - 当它被自动打破时块完成执行。
您的代码
查看代码,创建一个块并将其直接传递给dispatch_async
- 您永远不会在self
中存储对该块的引用。所以这里永远不会有任何循环,根本不需要搞弱参考。
一旦块创建strongSelf
有一个循环,然后使用@synchronized(strongSelf)
不会创建第二个循环,它只需锁定对象。当synchronized语句退出锁定时,当块退出强循环时,
HTH