是的,该@synchronized
指令是可重入的。请参阅线程编程指南中的使用 @synchronized指令以及ObjC 编程语言中的线程。
也就是说,你几乎不应该在 iOS 中使用它。在大多数情况下,您可以避免使用各种锁,更不用说重入锁之类的重量级(慢速)锁了。请参阅并发编程指南,特别是Migrating Away from Threads部分,了解 iOS 偏爱的基于队列的方法而不是手动线程管理和锁定的详细信息。
例如,读/写锁使用 Grand Central Dispatch 的工作方式如下:
- (id)init {
...
_someObjectQueue = dispatch_queue_create("com.myapp.someObject",
DISPATCH_QUEUE_CONCURRENT);
}
// In iOS 5 you need to release disptach_release(_someObjectQueue) in dealloc,
// but not in iOS 6.
- (id)someObject {
__block id result;
dispatch_sync(self.someObjectQueue, ^{
result = _someObject;
});
return result;
}
- (void)setSomeObject:(id)newValue {
dispatch_barrier_async(self.queue, ^{
_someObject = newValue;
});
这种方法允许使用独占写入器的无限并行读取器,同时确保写入器永远不会饿死,并且写入和读取是序列化的,同时避免任何内核调用,除非存在实际争用。这就是说它非常快速和简单。
当读者出现时,您将请求排队以读取该值,并等待它处理。当写入器出现时,它会将屏障请求排队以对其进行更新,这要求当前没有来自该队列的其他请求正在运行。使用这种结构,开发人员不需要管理任何锁。只需按照您希望它们运行的顺序将它们放入队列中。