如何防止从同一个线程重复访问代码块?
假设我有下一个代码:
func sendAnalytics() {
// some synchronous work
asyncTask() { _ in
completion()
}
}
我希望在调用完成之前阻止任何线程访问“//某些同步工作”。
objc_sync_enter(self)
objc_sync_exit(self)
似乎只是阻止从多个线程访问此代码,并且不会使我无法从单个线程访问此代码。有没有办法在不使用自定义解决方案的情况下正确执行此操作?
我反复访问,我的意思是多次从一个线程调用此sendAnalytics。假设,我有一个for,就像这样:
for i in 0...10 {
sendAnalytics()
}
每次下一次调用都不会等待sendAnalytics内部完成调用(显而易见)。在完成火灾之前,有没有办法让下一个电话等待?或者整个思维方式都是错误的,我必须在身体上更高地解决这个问题?
答案 0 :(得分:2)
您可以使用DispatchSemaphore
确保在下一次调用开始之前完成一次调用
let semaphore = DispatchSemaphore(value:1)
func sendAnalytics() {
self.semaphore.wait()
// some synchronous work
asyncTask() { _ in
completion()
self.semaphore.signal()
}
}
对sendAnalytics
的第二次调用将阻塞,直到第一个asyncTask完成。您应该小心不要阻止主队列,因为这会导致您的应用程序无响应。将sendAnalytics
调用发送到自己的串行调度队列以消除此风险可能更安全:
let semaphore = DispatchSemaphore(value:1)
let analyticsQueue = DispatchQueue(label:"analyticsQueue")
func sendAnalytics() {
analyticsQueue.async {
self.semaphore.wait()
// some synchronous work
asyncTask() { _ in
completion()
self.semaphore.signal()
}
}
}