Skip to content

Instantly share code, notes, and snippets.

@khanlou
Created November 11, 2016 19:44
Show Gist options
  • Save khanlou/2dc012e356fd372ecba845752d9a938a to your computer and use it in GitHub Desktop.
Save khanlou/2dc012e356fd372ecba845752d9a938a to your computer and use it in GitHub Desktop.
import Foundation
final class SafeSyncQueue {
struct QueueIdentity {
let label: String
}
let queue: DispatchQueue
fileprivate let queueKey: DispatchSpecificKey<QueueIdentity>
init(label: String) {
self.queue = DispatchQueue(label: "com.khanlou.\(label).SafeSyncQueue")
self.queueKey = DispatchSpecificKey<QueueIdentity>()
self.queue.setSpecific(key: queueKey, value: QueueIdentity(label: queue.label))
}
fileprivate var currentQueueIdentity: QueueIdentity? {
return DispatchQueue.getSpecific(key: queueKey)
}
func sync(execute: ()->()) {
if currentQueueIdentity?.label == queue.label {
execute()
} else {
queue.sync(execute: execute)
}
}
}
@tomlokhorst
Copy link

In general it is not safe to create a DispatchSpecificKey as an instance variable. Keys are compared by their address in memory, if you create and free multiple keys, they might end up sharing the same pointer. See my post on this issue: http://tom.lokhorst.eu/2018/02/leaky-abstractions-in-swift-with-dispatchqueue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment