在Swift 3中,如何检查当前线程?
在以前的Swift版本中,可以通过以下方式检查当前线程是否为主线程:
NSThread.isMainThread()
在Swift 3中,如何检查当前线程?
在以前的Swift版本中,可以通过以下方式检查当前线程是否为主线程:
NSThread.isMainThread()
看起来在Swift 3中只需使用Thread.isMainThread
即可。
Thread.isMainThread
会返回一个布尔值,指示您当前是否在主UI线程上。但它不会提供当前线程的信息,仅告诉您是否在主线程上。
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及以上版本:
Thread.isMainThread
返回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)
__dispatch_queue_get_label
不是 Swift 标准库的一部分,它只在 Apple 平台专用的框架中可用。例如,在 Ubuntu 上无法调用它。 - Xander Dunn__dispatch_queue_get_label(nil)
终于有东西可以用了,谢谢! - J. Doe通常,我们只需要知道代码被分派到哪个队列。因此,我将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
使用GCD时,可以使用dispatchPrecondition来检查进一步执行所必需的调度条件。如果您想要确保代码在正确的线程上执行,这将非常有用。例如:
DispatchQueue.main.async {
dispatchPrecondition(condition: .onQueue(DispatchQueue.global())) // will assert because we're executing code on main thread
}