zoukankan      html  css  js  c++  java
  • 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)
     }
    
  • 相关阅读:
    JDBC连接效率问题
    如何配置Filter过滤器处理JSP中文乱码(转)
    Servlet生命周期与工作原理(转)
    ANR触发原理
    SystemServer概述
    Zygote总结
    ART、JIT、AOT、Dalvik之间有什么关系?
    谈谈android缓存文件
    Activity启动过程全解析
    tombstone问题分析
  • 原文地址:https://www.cnblogs.com/duzhaoquan/p/14837933.html
Copyright © 2011-2022 走看看