假设我想在一个块内做@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
强引用(引用的对象 - 你明白了,变量并不重要,但被它引用的东西)blockVar
但blockVar
只有一个弱引用回self
。
然而,每次执行块时,它都会创建一个强引用(存储在strongSelf
中)来self
,因此创建一个动态循环 - 当块完成执行时会自动中断。
您的代码
查看您的代码,您创建一个块并将其直接传递给
dispatch_async
- 您永远不会在self
中存储对该块的引用。所以这里从来没有任何循环,根本不需要弄乱弱引用。一旦块创建了
strongSelf
就会有一个循环,那么使用@synchronized(strongSelf)
不会创建第二个循环,它只是锁定对象。当同步语句退出时,锁消失,当块退出时,强循环消失。
呵