单线程

时间:2017-04-07 08:10:10

标签: ios objective-c multithreading swift3

如何防止从同一个线程重复访问代码块?

假设我有下一个代码:

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内部完成调用(显而易见)。在完成火灾之前,有没有办法让下一个电话等待?或者整个思维方式都是错误的,我必须在身体上更高地解决这个问题?

1 个答案:

答案 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()
        }
     }
}