使用 GCD 在 Swift 3 中安全锁定变量

vik*_*vic 2 multithreading swift

如何锁定变量并防止不同线程同时更改它,从而导致错误?

我尝试使用

func lock(obj: AnyObject, blk:() -> ()) {
     objc_sync_enter(obj)
     blk()
     objc_sync_exit(obj)
}
Run Code Online (Sandbox Code Playgroud)

但我仍然有多线程问题。

Luc*_*tti 12

共享价值

如果您想以线程安全的方式访问共享值,如下所示

var list:[Int] = []
Run Code Online (Sandbox Code Playgroud)

调度队列

您可以创建自己的序列号DispatchQueue

let serialQueue = DispatchQueue(label: "SerialQueue")
Run Code Online (Sandbox Code Playgroud)

调度同步

现在不同的线程可以安全地访问list,您只需要将代码写入一个分派到您的串行队列的闭包中。

serialQueue.sync {
   // update list <---
}
// This line will always run AFTER the closure on the previous line 
Run Code Online (Sandbox Code Playgroud)

由于串行队列在一次执行闭包,因此访问list将是安全的。

请注意,前面的代码会阻塞当前线程,直到执行完闭包。

调度异步

如果不想在串行队列处理完闭包之前阻塞当前线程,则可以异步调度闭包

serialQueue.async {
   // update list <---
}
// This line can run BEFORE the closure on the previous line 
Run Code Online (Sandbox Code Playgroud)