我已经搜索了Swift的书籍,但找不到@synchronized的Swift版本。我如何做互斥在Swift?


当前回答

我自己也在寻找这个,并得出结论,在swift中还没有对此的原生构造。

我确实根据我从Matt Bridges和其他人那里看到的一些代码编写了这个小的帮助函数。

func synced(_ lock: Any, closure: () -> ()) {
    objc_sync_enter(lock)
    closure()
    objc_sync_exit(lock)
}

用法非常简单

synced(self) {
    println("This is a synchronized closure")
}

我发现了一个问题。在这一点上,传入一个数组作为lock参数似乎会导致一个非常迟钝的编译器错误。除此之外,虽然它似乎工作如所愿。

Bitcast requires both operands to be pointer or neither
  %26 = bitcast i64 %25 to %objc_object*, !dbg !378
LLVM ERROR: Broken function found, compilation aborted!

其他回答

我喜欢并使用了这里的许多答案,所以我会选择最适合你的。也就是说,当我需要objective-c的@synchronized时,我更喜欢使用swift 2中引入的defer语句。

{ 
    objc_sync_enter(lock)
    defer { objc_sync_exit(lock) }

    //
    // code of critical section goes here
    //

} // <-- lock released when this block is exited

这个方法的好处是,你的临界区可以以任何想要的方式退出包含块(例如,return, break, continue, throw),并且“不管程序控制如何转移,defer语句中的语句都将被执行”。1

要添加返回函数,你可以这样做:

func synchronize<T>(lockObj: AnyObject!, closure: ()->T) -> T
{
  objc_sync_enter(lockObj)
  var retVal: T = closure()
  objc_sync_exit(lockObj)
  return retVal
}

随后,你可以调用它使用:

func importantMethod(...) -> Bool {
  return synchronize(self) {
    if(feelLikeReturningTrue) { return true }
    // do other things
    if(feelLikeReturningTrueNow) { return true }
    // more things
    return whatIFeelLike ? true : false
  }
}

图我将发布我的Swift 5实现,建立在前面的答案。谢谢你们了!我发现有一个返回值的方法也很有用,所以我有两个方法。

这是一个简单的类首先创建:

import Foundation
class Sync {
public class func synced(_ lock: Any, closure: () -> ()) {
        objc_sync_enter(lock)
        defer { objc_sync_exit(lock) }
        closure()
    }
    public class func syncedReturn(_ lock: Any, closure: () -> (Any?)) -> Any? {
        objc_sync_enter(lock)
        defer { objc_sync_exit(lock) }
        return closure()
    }
}

如果需要返回值,就像这样使用它:

return Sync.syncedReturn(self, closure: {
    // some code here
    return "hello world"
})

Or:

Sync.synced(self, closure: {
    // do some work synchronously
})

基于ɲ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

我自己也在寻找这个,并得出结论,在swift中还没有对此的原生构造。

我确实根据我从Matt Bridges和其他人那里看到的一些代码编写了这个小的帮助函数。

func synced(_ lock: Any, closure: () -> ()) {
    objc_sync_enter(lock)
    closure()
    objc_sync_exit(lock)
}

用法非常简单

synced(self) {
    println("This is a synchronized closure")
}

我发现了一个问题。在这一点上,传入一个数组作为lock参数似乎会导致一个非常迟钝的编译器错误。除此之外,虽然它似乎工作如所愿。

Bitcast requires both operands to be pointer or neither
  %26 = bitcast i64 %25 to %objc_object*, !dbg !378
LLVM ERROR: Broken function found, compilation aborted!