如何检查 Swift 3中哪个是当前线程?
在早期版本的 Swift 中,可以通过以下方法检查当前线程是否是主线程:
NSThread.isMainThread()
看起来就像是雨燕3里的 Thread.isMainThread。
Thread.isMainThread
Thread.isMainThread将返回一个布尔值,指示您当前是否在主 UI 线程上。但是这不会给你当前的线程。它只会告诉你你是否在主线上。
Thread.current将返回当前所在的线程。
Thread.current
我做了一个扩展来打印线程和队列:
extension Thread { class func printCurrent() { print("\r⚡️: \(Thread.current)\r" + "🏭: \(OperationQueue.current?.underlyingQueue?.label ?? "None")\r") } }
Thread.printCurrent()
结果将是:
⚡️: <NSThread: 0x604000074380>{number = 1, name = main} 🏭: com.apple.main-thread
也建议使用:
extension DispatchQueue { /// - Parameter closure: Closure to execute. func dispatchMainIfNeeded(_ closure: @escaping VoidCompletion) { guard self === DispatchQueue.main && Thread.isMainThread else { DispatchQueue.main.async(execute: closure) return } closure() } } DispatchQueue.main.dispatchMainIfNeeded { ... }
在最新的 Swift 4.0 ~ 4.2中,我们可以使用 Thread.current
参见 返回表示当前执行线程的线程对象
迅捷4及以上:
Thread.isMainThread返回 Bool,说明如果用户在 Main Thread 或 Not 上,如果有人想打印队列/线程的名称,这个扩展将是有帮助的
Bool
extension Thread { var threadName: String { if let currentOperationQueue = OperationQueue.current?.name { return "OperationQueue: \(currentOperationQueue)" } else if let underlyingDispatchQueue = OperationQueue.current?.underlyingQueue?.label { return "DispatchQueue: \(underlyingDispatchQueue)" } else { let name = __dispatch_queue_get_label(nil) return String(cString: name, encoding: .utf8) ?? Thread.current.description } } }
使用方法:
print(Thread.current.threadName)
使用 GCD 时,可以使用 前提条件检查进一步执行所必需的分派条件。如果希望保证代码在正确的线程上执行,这可能非常有用。例如:
DispatchQueue.main.async { dispatchPrecondition(condition: .onQueue(DispatchQueue.global())) // will assert because we're executing code on main thread }
通常,我们只需要知道代码被分派到哪个队列。因此,我将 threadName和 queueName分成不同的属性,以使其更加清晰。
threadName
queueName
extension Thread { var threadName: String { if isMainThread { return "main" } else if let threadName = Thread.current.name, !threadName.isEmpty { return threadName } else { return description } } var queueName: String { if let queueName = String(validatingUTF8: __dispatch_queue_get_label(nil)) { return queueName } else if let operationQueueName = OperationQueue.current?.name, !operationQueueName.isEmpty { return operationQueueName } else if let dispatchQueueName = OperationQueue.current?.underlyingQueue?.label, !dispatchQueueName.isEmpty { return dispatchQueueName } else { return "n/a" } } }
用例:
DispatchQueue.main.async { print(Thread.current.threadName) print(Thread.current.queueName) } // main // com.apple.main-thread
DispatchQueue.global().async { print(Thread.current.threadName) print(Thread.current.queueName) } // <NSThread: 0x600001cd9d80>{number = 3, name = (null)} // com.apple.root.default-qos