GCD获取当前队 Get current dispatch queue
iOS开发中GCD获取当前队列 如果iOS6之前可以使用" dispatch_get_current_queue()"获取当前队列,但是 iOS 6.1 SDK之后就废弃了
如果使用OperationQueue可以使用OperationQueue.current?.underlyingQueue
如果在单纯的GCD中想要获取当前对列是比较困的,可以使用设置关联对象的方法间接实现。
具体办法是,DispatchQueue有两个实例方法setSpecific和getSpecific,分别用于设置和获取关联对象,DispatchQueue有个类方法getSpecific,可以获取到当前环境的关联对象Returns the value for the key associated with the current execution context.
给每个queue都设置一个关联的结构体,结构体中引用用该queue本身,采用若引用防止循环引用。这样在获取DispatchQueue.getSpecific就可以获取到,必须注意的是创建队列的时候要记得设置关联对象
代码实现如下:
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 } convenience init(label:String,registerDetection:Bool){ self.init(label:label) if registerDetection{ DispatchQueue._registerDetection(of: [self], key: DispatchQueue.key) } } }
具体用法:
1.检测系统队列 DispatchQueue.currentQueueLabel DispatchQueue.current DispatchQueue.global(qos: .default) == DispatchQueue.current DispatchQueue.main === DispatchQueue.current 2.定义的队列 let queue = DispatchQueue(label: "queue-sample") DispatchQueue.registerDetection(of: queue) //或者 DispatchQueue(label: "queue-sample", registerDetection: true) if DispatchQueue.current == queue { ... }
判定 queue条件API:dispatchPrecondition
//当前的队列是否符合条件的队列,符合条件才往下执行,不符合条件就把当前queue阻塞了,所以不要在系统queue中使用,main queue、global queue等 //dispatchPrecondition(condition: .onQueue(DispatchQueue.current)) 条件有三种枚举 public enum DispatchPredicate { case onQueue(DispatchQueue) case onQueueAsBarrier(DispatchQueue) case notOnQueue(DispatchQueue) }