Swift 如何获取当前队列名称?

81 阅读1分钟

你还将学到如何在 Swift 中调用 C 库函数,太赚啦!

用私有 API :dispatch_get_current_queue

extension DispatchQueue {
    private static let dispatch_get_current_queue = dlsym(dlopen(nil, RTLD_GLOBAL), "dispatch_get_current_queue")

    static var current: DispatchQueue {
        dispatch_get_current_queue.map {
            unsafeBitCast($0, to: (@convention(c) () -> Unmanaged<DispatchQueue>).self)().takeUnretainedValue()
        } ?? .global(qos: .background)
    }
}

代码来源:EricRabil: Get current dispatch queue in Swift (github.com)

导入动态链接库中的符号

  • 用到了私有 API :dispatch_get_current_queue,第一句就是用来加载这个包含这个私有 API 的库
  • dlsym 用于从动态库中查找符号,也就是本文的主人公 “dispatch_get_current_queue
  • dlopen(nil, RTLD_GLOBAL):打开主程序的动态链接库,并使得所有符号在全局范围内可见(RTLD_GLOBAL)

获取当前队列

  • 上面导入了 dispatch_get_current_queue ,然后用它来获取当前队列
  • map 函数的作用是解包,因为 dispatch_get_current_queue 返回值可能为空,如果为空则返回全局队列
  • unsafe​Bit​Cast 类型转换,把 dispatch_get_current_queue 返回的符号指针转成函数指针。 Apple Developer 文档
  • (@convention(c) () -> Unmanaged< DispatchQueue>).self: 把低级 C 函数转成 Swift 函数,从而在 Swift 中能够被调用

这也展示了如何在 Swift 中调用 C 库函数

参考资料