Based on Oleg Barinov answer
Details
Solution
import Foundation
// MARK: private functionality
extension DispatchQueue {
private struct QueueReference { weak var queue: DispatchQueue? }
private static let key: DispatchSpecificKey<QueueReference> = {
let key = DispatchSpecificKey<QueueReference>()
setupSystemQueuesDetection(key: key)
return key
}()
private static func _registerDetection(of queues: [DispatchQueue], key: DispatchSpecificKey<QueueReference>) {
queues.forEach { $0.setSpecific(key: key, value: QueueReference(queue: $0)) }
}
private static func setupSystemQueuesDetection(key: DispatchSpecificKey<QueueReference>) {
let queues: [DispatchQueue] = [
.main,
.global(qos: .background),
.global(qos: .default),
.global(qos: .unspecified),
.global(qos: .userInitiated),
.global(qos: .userInteractive),
.global(qos: .utility)
]
_registerDetection(of: queues, key: key)
}
}
// MARK: public functionality
extension DispatchQueue {
static func registerDetection(of queue: DispatchQueue) {
_registerDetection(of: [queue], key: key)
}
static var currentQueueLabel: String? { current?.label }
static var current: DispatchQueue? { getSpecific(key: key)?.queue }
}
Usage
Detect system queue
DispatchQueue.currentQueueLabel
DispatchQueue.current
DispatchQueue.global(qos: .default) == DispatchQueue.current
DispatchQueue.main === DispatchQueue.current
Detect custom queue
let queue = DispatchQueue(label: "queue-sample")
DispatchQueue.registerDetection(of: queue)
if DispatchQueue.current == queue { ... }
Sample
func subTest(queue: DispatchQueue) {
queue.async {
print("--------------------------------------------------------")
print("queue label: \(DispatchQueue.currentQueueLabel ?? "nil")")
print("print DispatchQueue.current: \(String(describing: DispatchQueue.current))")
print("print queue == DispatchQueue.current: \(queue == DispatchQueue.current)")
print("print queue === DispatchQueue.current: \(queue === DispatchQueue.current)")
print("DispatchQueue.main == DispatchQueue.current: \(DispatchQueue.main == DispatchQueue.current)\n")
}
}
func test() {
subTest(queue: DispatchQueue.main)
sleep(1)
subTest(queue: DispatchQueue.global(qos: .default))
sleep(1)
subTest(queue: DispatchQueue.global(qos: .utility))
sleep(1)
let queue = DispatchQueue(label: "queue-sample")
DispatchQueue.registerDetection(of: queue)
subTest(queue: queue)
sleep(1)
}
test()
DispatchQueue.global(qos: .default).async {
test()
}
Sample Output
--------------------------------------------------------
queue label: com.apple.root.default-qos
print DispatchQueue.current: Optional(<OS_dispatch_queue_global: com.apple.root.default-qos[0x7fff89eb47c0] = { xref = -2147483648, ref = -2147483648, sref = 1, target = [0x0], width = 0xfff, state = 0x0060000000000000, in-barrier}>)
print queue == DispatchQueue.current: true
print queue === DispatchQueue.current: true
DispatchQueue.main == DispatchQueue.current: false
--------------------------------------------------------
queue label: com.apple.root.utility-qos
print DispatchQueue.current: Optional(<OS_dispatch_queue_global: com.apple.root.utility-qos[0x7fff89eb46c0] = { xref = -2147483648, ref = -2147483648, sref = 1, target = [0x0], width = 0xfff, state = 0x0060000000000000, in-barrier}>)
print queue == DispatchQueue.current: true
print queue === DispatchQueue.current: true
DispatchQueue.main == DispatchQueue.current: false
--------------------------------------------------------
queue label: queue-sample
print DispatchQueue.current: Optional(<OS_dispatch_queue_serial: queue-sample[0x600000275780] = { xref = 7, ref = 3, sref = 2, target = com.apple.root.default-qos.overcommit[0x7fff89eb4840], width = 0x1, state = 0x0060002500000b01, enqueued, max qos 5, draining on 0xb03, in-barrier}>)
print queue == DispatchQueue.current: true
print queue === DispatchQueue.current: true
DispatchQueue.main == DispatchQueue.current: false
--------------------------------------------------------
queue label: com.apple.main-thread
print DispatchQueue.current: Optional(<OS_dispatch_queue_main: com.apple.main-thread[0x7fff89eb43c0] = { xref = -2147483648, ref = -2147483648, sref = 1, target = com.apple.root.default-qos.overcommit[0x7fff89eb4840], width = 0x1, state = 0x001ffe9000000300, dirty, in-flight = 0, thread = 0x303 }>)
print queue == DispatchQueue.current: true
print queue === DispatchQueue.current: true
DispatchQueue.main == DispatchQueue.current: true
--------------------------------------------------------
queue label: com.apple.main-thread
print DispatchQueue.current: Optional(<OS_dispatch_queue_main: com.apple.main-thread[0x7fff89eb43c0] = { xref = -2147483648, ref = -2147483648, sref = 1, target = com.apple.root.default-qos.overcommit[0x7fff89eb4840], width = 0x1, state = 0x001ffe9000000300, dirty, in-flight = 0, thread = 0x303 }>)
print queue == DispatchQueue.current: true
print queue === DispatchQueue.current: true
DispatchQueue.main == DispatchQueue.current: true
--------------------------------------------------------
queue label: com.apple.root.default-qos
print DispatchQueue.current: Optional(<OS_dispatch_queue_global: com.apple.root.default-qos[0x7fff89eb47c0] = { xref = -2147483648, ref = -2147483648, sref = 1, target = [0x0], width = 0xfff, state = 0x0060000000000000, in-barrier}>)
print queue == DispatchQueue.current: true
print queue === DispatchQueue.current: true
DispatchQueue.main == DispatchQueue.current: false
--------------------------------------------------------
queue label: com.apple.root.utility-qos
print DispatchQueue.current: Optional(<OS_dispatch_queue_global: com.apple.root.utility-qos[0x7fff89eb46c0] = { xref = -2147483648, ref = -2147483648, sref = 1, target = [0x0], width = 0xfff, state = 0x0060000000000000, in-barrier}>)
print queue == DispatchQueue.current: true
print queue === DispatchQueue.current: true
DispatchQueue.main == DispatchQueue.current: false
--------------------------------------------------------
queue label: queue-sample
print DispatchQueue.current: Optional(<OS_dispatch_queue_serial: queue-sample[0x60000027a280] = { xref = 7, ref = 3, sref = 2, target = com.apple.root.default-qos.overcommit[0x7fff89eb4840], width = 0x1, state = 0x0060002500000b01, enqueued, max qos 5, draining on 0xb03, in-barrier}>)
print queue == DispatchQueue.current: true
print queue === DispatchQueue.current: true
DispatchQueue.main == DispatchQueue.current: false