You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Obj-C中@synchronized的key在Swift GCD中的等价实现是什么?

Obj-C @synchronized 与 Swift GCD 同步的等价机制

核心对应关系

@synchronized(obj) 本质是通过传入的obj作为唯一标识,为代码块创建互斥锁,保证同一时间仅一个线程能执行该代码。在GCD中,自定义串行队列是最直接的等价机制——你可以把这个队列当作"key",同一队列下的任务会串行执行,天然实现同步;另外也可以用**Dispatch Semaphore(信号量)**模拟基于对象的锁逻辑,更贴近@synchronized的锁语义。

方式一:自定义串行队列(推荐)

这是GCD中最常用的同步实现方式,和@synchronized的"key"思路完全对应:每个需要同步的逻辑对应一个专属串行队列,不同队列(不同key)之间的任务互不干扰。

Obj-C @synchronized 示例

@interface MyClass ()
@property (nonatomic, strong) NSObject *syncLock;
@end

@implementation MyClass
- (instancetype)init {
    self = [super init];
    if (self) {
        _syncLock = [[NSObject alloc] init];
    }
    return self;
}

- (void)executeSyncTask {
    @synchronized(self.syncLock) {
        // 需要同步执行的代码
        NSLog(@"执行同步任务");
    }
}
@end

Swift GCD 等价实现

class MyClass {
    // 专属串行队列作为同步标识(对应@synchronized的key)
    private let syncQueue = DispatchQueue(label: "com.myapp.sync.queue")

    func executeSyncTask() {
        syncQueue.sync {
            // 需要同步执行的代码
            print("执行同步任务")
        }
    }
}

这里的syncQueue就等同于@synchronized里的syncLock对象,同一队列的任务会严格串行执行,保证线程安全。如果需要多组独立的同步逻辑,只需创建多个不同标识的串行队列即可。

方式二:Dispatch Semaphore(模拟对象锁)

如果想更贴近@synchronized"基于对象的互斥锁"语义,可以用信号量实现:为每个作为key的对象关联一个信号量,通过wait()和signal()控制代码块的访问权限。

Swift 示例

class MyClass {
    // 存储key与对应信号量的映射表
    private var semaphoreMap = [AnyHashable: DispatchSemaphore]()
    // 保护映射表的串行队列(避免多线程读写冲突)
    private let mapAccessQueue = DispatchQueue(label: "com.myapp.semaphore.map")

    func executeSyncTask(withKey key: AnyHashable) {
        // 线程安全地获取或创建key对应的信号量
        let semaphore = mapAccessQueue.sync { () -> DispatchSemaphore in
            if let existing = semaphoreMap[key] {
                return existing
            }
            let newSemaphore = DispatchSemaphore(value: 1)
            semaphoreMap[key] = newSemaphore
            return newSemaphore
        }

        semaphore.wait()
        defer {
            semaphore.signal()
        }

        // 需要同步执行的代码
        print("基于key执行同步任务")
    }
}

这种方式完全复刻@synchronized的底层逻辑,但实现复杂度高于串行队列,仅在需要严格匹配"对象作为锁key"的场景下使用。

注意事项

  • 串行队列的sync方法会阻塞当前线程,若在主线程调用可能引发死锁,无需等待执行结果时,优先用async更安全。
  • @synchronized会自动处理异常(代码块抛出异常也会释放锁);GCD串行队列天然无需手动释放锁,但信号量方式必须用defer确保signal()执行,避免死锁。

内容的提问来源于stack exchange,提问作者Snowtown123

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 05:27:32