我已经搜索了Swift的书籍,但找不到@synchronized的Swift版本。我如何做互斥在Swift?
当前回答
在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对象发送解锁消息时,必须确保该消息是从发送初始锁定消息的同一个线程发送的。从不同的线程解锁锁可能会导致未定义的行为。
其他回答
图我将发布我的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
你可以把语句夹在objc_sync_enter(obj: AnyObject?)和objc_sync_exit(obj: AnyObject?)之间。@synchronized关键字在幕后使用这些方法。即。
objc_sync_enter(self)
... synchronized code ...
objc_sync_exit(self)
我喜欢并使用了这里的许多答案,所以我会选择最适合你的。也就是说,当我需要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
总之,这里给出了更常见的方法,包括返回值或void和throw
import Foundation
extension NSObject {
func synchronized<T>(lockObj: AnyObject!, closure: () throws -> T) rethrows -> T
{
objc_sync_enter(lockObj)
defer {
objc_sync_exit(lockObj)
}
return try closure()
}
}
推荐文章
- 在Swift中转换字符串为日期
- 点击按钮时如何打开手机设置?
- 在Swift中使用自定义消息抛出错误/异常的最简单方法?
- 编译器错误:带有Objective-C选择器的方法与前面带有相同Objective-C选择器的声明冲突
- 如何在Swift中获得唯一的设备ID ?
- 如何在Swift中获得枚举值的名称?
- 互斥实例/教程?
- 如何调用手势点击在UIView编程在迅速
- 什么是Swift相当于respondsToSelector?
- dyld:库未加载:@rpath/libswift_stdlib_core.dylib
- 我如何隐藏在一个Swift iOS应用程序的状态栏?
- 以编程方式更改导航标题
- 我如何得到一个plist作为一个字典在Swift?
- 如何在Swift中删除视图的所有子视图?
- 属性getter和setter