我已经搜索了Swift的书籍,但找不到@synchronized的Swift版本。我如何做互斥在Swift?
当前回答
斯威夫特3
此代码具有重入能力,可以与异步函数调用一起工作。在这段代码中,someAsyncFunc()被调用之后,串行队列上的另一个函数闭包将被处理,但会被semapore .wait()阻塞,直到signal()被调用。internalQueue。不应该使用sync,因为如果我没有弄错的话,它会阻塞主线程。
let internalQueue = DispatchQueue(label: "serialQueue")
let semaphore = DispatchSemaphore(value: 1)
internalQueue.async {
self.semaphore.wait()
// Critical section
someAsyncFunc() {
// Do some work here
self.semaphore.signal()
}
}
如果没有错误处理,Objc_sync_enter /objc_sync_exit不是一个好主意。
其他回答
是什么
final class SpinLock {
private let lock = NSRecursiveLock()
func sync<T>(action: () -> T) -> T {
lock.lock()
defer { lock.unlock() }
return action()
}
}
类似于Objective-C中的@synchronized指令,在Swift中可以有任意的返回类型和漂亮的重抛出行为。
// Swift 3
func synchronized<T>(_ lock: AnyObject, _ body: () throws -> T) rethrows -> T {
objc_sync_enter(lock)
defer { objc_sync_exit(lock) }
return try body()
}
使用defer语句可以直接返回一个值,而不需要引入临时变量。
在Swift 2中,为闭包添加@noescape属性可以进行更多的优化:
// Swift 2
func synchronized<T>(lock: AnyObject, @noescape _ body: () throws -> T) rethrows -> T {
objc_sync_enter(lock)
defer { objc_sync_exit(lock) }
return try body()
}
基于GNewc[1](我喜欢任意返回类型)和Tod Cunningham[2](我喜欢延迟)的答案。
你可以把语句夹在objc_sync_enter(obj: AnyObject?)和objc_sync_exit(obj: AnyObject?)之间。@synchronized关键字在幕后使用这些方法。即。
objc_sync_enter(self)
... synchronized code ...
objc_sync_exit(self)
在Swift4中使用NSLock:
let lock = NSLock()
lock.lock()
if isRunning == true {
print("Service IS running ==> please wait")
return
} else {
print("Service not running")
}
isRunning = true
lock.unlock()
警告 NSLock类使用POSIX线程来实现它的锁定行为。当向NSLock对象发送解锁消息时,必须确保该消息是从发送初始锁定消息的同一个线程发送的。从不同的线程解锁锁可能会导致未定义的行为。
为什么要让锁变得困难和麻烦呢? 使用分派障碍。
调度障碍在并发队列中创建同步点。 当它正在运行时,队列上的其他块都不允许运行,即使它是并发的并且其他内核可用。 如果这听起来像一个排他(写)锁,它是。 无障碍块可以被认为是共享(读)锁。 只要所有对资源的访问都是通过队列执行的,barrier就能提供非常廉价的同步。
推荐文章
- 如何停止不必要的UIButton动画标题变化?
- 如何使用Swift播放声音?
- 如何解散ViewController在Swift?
- 保存字符串到NSUserDefaults?
- 如何将JSON字符串转换为字典?
- 什么是NSLocalizedString等效在Swift?
- 如何创建一个字符串的格式?
- 获取最顶端的UIViewController
- 使用isKindOfClass与Swift
- SourceKitService终止
- 我如何在Swift中解析/创建一个以分数秒UTC时区(ISO 8601, RFC 3339)格式化的日期时间戳?
- 如何使用@Binding变量实现自定义初始化
- Swift设置为Array
- 如何设置回退按钮文本在Swift
- 我如何能在Swift扩展类型化数组?