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)
 }
原文地址:https://www.cnblogs.com/duzhaoquan/p/14837933.html