什么是Swift中等同于Objective-C的"@synchronized"的方法?

267
我查阅了Swift书籍,但未能找到@synchronized的Swift版本。在Swift中如何实现互斥?

1
我会使用调度栅栏。栅栏提供非常便宜的同步。dispatch_barrier_async()等。 - Frederick C. Lee
@FrederickC.Lee,如果您需要同步写入,例如在为removeFirst()创建包装器时,该怎么办? - ScottyBlades
24个回答

0
为什么要使用锁来增加复杂性和麻烦呢? 使用 Dispatch Barriers 吧。
Dispatch Barriers 在并发队列中创建了同步点。 在它运行时,即使是并发的且其他核心可用的其他块也不允许运行。 如果这听起来像一个排他(写)锁,那就是它的作用。 非 barrier 块可以被认为是共享(读)锁。 只要所有对资源的访问都通过队列进行,barriers 就提供了非常便宜的同步。

2
我的意思是,你假设使用GCD队列来同步访问,但原始问题中并没有提到。而且只有在并发队列中才需要屏障-您可以使用串行队列来排队互斥块以模拟锁定。 - Bill
我的问题是,模拟锁的原因是什么?根据我所了解的,由于与队列内部屏障相比,使用锁会增加开销,因此不建议使用锁。 - Frederick C. Lee

0

dispatch_barrier_async是更好的方式,而不会阻塞当前线程。

dispatch_barrier_async(accessQueue, { dictionary[object.ID] = object })


-1

基于ɲeuroburɳ,测试一个子类案例

class Foo: NSObject {
    func test() {
        print("1")
        objc_sync_enter(self)
        defer {
            objc_sync_exit(self)
            print("3")
        }

        print("2")
    }
}


class Foo2: Foo {
    override func test() {
        super.test()

        print("11")
        objc_sync_enter(self)
        defer {
            print("33")
            objc_sync_exit(self)
        }

        print("22")
    }
}

let test = Foo2()
test.test()

输出:

1
2
3
11
22
33

-5
另一种方法是创建一个超类,然后继承它。这样你就可以更直接地使用GCD了。
class Lockable {
    let lockableQ:dispatch_queue_t

    init() {
        lockableQ = dispatch_queue_create("com.blah.blah.\(self.dynamicType)", DISPATCH_QUEUE_SERIAL)
    }

    func lock(closure: () -> ()) {
        dispatch_sync(lockableQ, closure)
    }
}


class Foo: Lockable {

    func boo() {
        lock {
            ....... do something
        }
    }

10
如果您不需要子类型多态性,请避免继承以减少耦合。不要懒惰,倾向于使用组合进行代码重用。 - Jano

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