GCD swift 4 线程安全

Ser*_*zov 2 grand-central-dispatch swift

我有一个控制一些资源的功能,例如:

var resource: Int?

func changeSomeResources() {
    resource = 1
    // rewriting keychain parameters
    // working with UIApplication.shared
}
Run Code Online (Sandbox Code Playgroud)

然后我多次将此函数添加到全局线程

DispatchQueue.global(qos: .userInitiated).async {
    changeSomeResources()
}
DispatchQueue.global(qos: .userInitiated).async {
    changeSomeResources()
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,除了竞争条件之外,我是否会遇到一些线程问题?例如,如果两个函数将尝试同时更改资源

Mar*_*n R 5

全局调度队列是并发的,因此不能保护您的函数不被多个线程同时调用。

如果要序列化对资源的访问,则必须创建一个串行队列:

let myQueue = DispatchQueue(label: "myQueue", qos: .userInitiated)
Run Code Online (Sandbox Code Playgroud)

然后分派到这个队列的所有工作项按顺序执行:

myQueue.async {
    changeSomeResources()
}
Run Code Online (Sandbox Code Playgroud)

另请注意,UIApplication作为 UI 相关资源,只能在主线程上访问:

DispatchQueue.main.async {
    // working with UIApplication.shared
}
Run Code Online (Sandbox Code Playgroud)

Xcode 还具有选项“Thread Sanitizer”和“Main Thread Checker”(在方案设置的“Diagnostics”窗格中),可以帮助检测线程问题。