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

Posted

技术标签:

【中文标题】在类函数中使用 @synchronized(self) ...【英文标题】:Using @synchronized(self) ...  in class-function在类函数中使用 @synchronized(self) ...  【发布时间】:2012-03-22 13:54:53 【问题描述】:

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

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

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

我只是出于好奇。

【问题讨论】:

我曾经在我的博客here 中讨论过同样的事情。也许看看它。 【参考方案1】:

self 在此实例中指的是类,而不是实例。在 ObjC 中,类本身就是对象。

【讨论】:

如果一个类是一个对象,它的实例是什么? 我认为它是“Class”类的一个实例。 [someNSObject 类] 记录为 +(Class)class 类对象是元类的一个实例,它是 ObjC 运行时自动创建的。类的“类方法”实际上只是元类上的实例方法,这就是类对象响应所有这些方法的原因。 传递给@synchronized指令的对象是用于区分受保护块的唯一标识符。如果您在两个不同的线程中执行上述方法,为每个线程上的 anObj 参数传递不同的对象,则每个线程都将获取其锁定并继续处理而不会被另一个线程阻塞。但是,如果在两种情况下都传递相同的对象,则其中一个线程将首先获取锁,而另一个线程将阻塞,直到第一个线程完成临界区【参考方案2】:

self 在这种情况下是类本身,在类函数中使用 @synchronized 非常好,因为它们也是 Objective-C 对象。

【讨论】:

所以它会像 [TheClass 类]?【参考方案3】:

@synchronized 语法是互斥体实现的编译器扩展。我假设你理解what it does。编译器会将其翻译成其他内容,据说类似于critical section,因为它占用的 CPU 较少。需要跟踪锁。该实现将使用一个对象来记录锁的状态,以保持其完整性(即一个锁不应该被获取两次,或者解锁两次)。

@synchronized(self) 中,对象不必是self。它可以是任何objective-c 对象。请注意,单个 @synchronized 块通常什么都不做(当您提到它不起作用时,它实际上表现正确)。但是当同一个对象上有两个@synchronized块时,只会同时执行一个块,另一个块必须等待锁被解锁(即第一个块完成)。这有助于在多线程环境中保持同步。

【讨论】:

在这种语法上查看 ObjC docs 似乎比 Java 文档更有用。【参考方案4】:

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

【讨论】:

以上是关于在类函数中使用 @synchronized(self) ...的主要内容,如果未能解决你的问题,请参考以下文章

1Python全栈之路系列之面向基础

并发编程之单例模式,volatile和 synchronized

Java并发编程之synchronized

iOS开发基础知识--碎片45

私有属性私有方法

python PEP8规范