在类函数中使用 @synchronized(self) { ... }

11

我在一个类方法中意外地使用了带有信号量self@synchronized块。

+(void)someFunction {
    @synchronized(self) {
         /* some code */
    }
}

这似乎是有效的代码,至少编译器没有给我任何不良反馈。我的问题是:这里的self是什么?据我所知,@synchronized块没有起作用,但它也没有崩溃。

我只是出于好奇而问。


1
我曾在我的博客这里中讨论过同样的事情。也许你可以看一下。 - Vignesh
4个回答

13
在这种情况下,self指的是类本身,而不是实例。在ObjC中,类本身也是对象。

3
如果一个类是一个对象,它的实例是什么? - James Bedford
我认为这是类“Class”的一个实例。[someNSObject class]的文档记录为+(Class)class。 - Max
7
类对象是元类的一个实例,ObjC运行时会自动创建。一个类的“类方法”其实就是在元类上的实例方法,这就是为什么类对象能够响应所有这些方法的原因。 - BJ Homer
1
传递给@synchronized指令的对象是一个唯一标识符,用于区分受保护的块。如果您在两个不同的线程中执行前面的方法,并在每个线程上为anObj参数传递不同的对象,则每个线程都会获取其锁并继续处理,而不会被其他线程阻塞。但是,如果在这两种情况下都传递相同的对象,则其中一个线程将首先获取锁,而另一个线程将被阻塞,直到第一个线程完成关键部分。 - Abdul Yasin

4
在这个上下文中,“self”指的是类本身,在一个类函数中使用“@synchronized”是完全可行的,因为它们也是Objective-C对象。

1
[TheClass class]? - Max

3
@synchronized语法是一种编译器扩展,用于互斥量实现。我假设你理解它的作用。编译器将把它转换成其他东西,可能类似于临界区,因为它的CPU使用率较低。需要跟踪锁。该实现将使用一个对象来记录锁的状态,以保持其完整性(即锁不应被获取两次或解锁两次)。
@synchronized(self)中,对象不必是self。它可以是任何Objective-C对象。请注意,单个@synchronized块通常什么也不做(当你说它不起作用时,实际上它是正确行为)。但是当您在同一对象上有两个@synchronized块时,只有一个块将同时执行,另一个块必须等待锁被解锁(即第一个块完成)。这有助于在多线程环境中保持同步。

似乎查看ObjC文档上的语法比Java文档更有用。 - jscs

0
在类方法中,self 是调用该方法的类。例如,您可以使用 self 调用同一类的其他类方法。 [MyClass someFunction][self someFunction] 相当于递归调用 someFunction。我确定 @synchronized 块按预期工作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接