我已经搜索了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!

其他回答

我自己也在寻找这个,并得出结论,在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!

你可以使用GCD。它比@synchronized更详细一点,但可以作为替代品:

let serialQueue = DispatchQueue(label: "com.test.mySerialQueue")
serialQueue.sync {
    // code
}

图我将发布我的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
})

在现代Swift 5中,具有返回功能:

/**
Makes sure no other thread reenters the closure before the one running has not returned
*/
@discardableResult
public func synchronized<T>(_ lock: AnyObject, closure:() -> T) -> T {
    objc_sync_enter(lock)
    defer { objc_sync_exit(lock) }

    return closure()
}

像这样使用它,以利用返回值功能:

let returnedValue = synchronized(self) { 
     // Your code here
     return yourCode()
}

或者像这样:

synchronized(self) { 
     // Your code here
    yourCode()
}

试题:NSRecursiveLock

一种锁,可以被同一线程多次获得 导致死锁。

let lock = NSRecursiveLock()

func f() {
    lock.lock()
    //Your Code
    lock.unlock()
}

func f2() {
    lock.lock()
    defer {
        lock.unlock()
    }
    //Your Code
}

Objective-C同步特性支持递归和 可重入代码。线程可以多次使用同一个信号量 递归的方式;其他线程被阻止使用它,直到 线程释放使用它获得的所有锁;也就是说,每一个 @synchronized()块正常退出或通过异常退出。 源