How do I check which one is the current thread in Swift 3?
In previous versions of Swift it was possible to check if the current thread was the main one by doing this:
NSThread.isMainThread()
How do I check which one is the current thread in Swift 3?
In previous versions of Swift it was possible to check if the current thread was the main one by doing this:
NSThread.isMainThread()
Thread.isMainThread
will return a boolean indicating if you're currently on the main UI thread. But this will not give you the current thread. It will only tell you if you are on the main or not.
Thread.current
will return the current thread you are on.
I've made an extension to print the thread and queue:
extension Thread {
class func printCurrent() {
print("\r⚡️: \(Thread.current)\r" + ": \(OperationQueue.current?.underlyingQueue?.label ?? "None")\r")
}
}
Thread.printCurrent()
The result would be:
⚡️: <NSThread: 0x604000074380>{number = 1, name = main}
: com.apple.main-thread
Also recommend to use:
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 and above:
Thread.isMainThread
returns Bool
stating that if the user is on Main Thread or Not, in case if someone wants to print the name of the queue/thread this extension will be helpful
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
}
}
}
How to use:
print(Thread.current.threadName)
Normally, we only need to know which queue the code is dispatched. So I separate the threadName
and queueName
into different properties to make it more clear.
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"
}
}
}
Use cases:
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
When using GCD you can use dispatchPrecondition to check a dispatch condition necessary for further execution. This can be useful if you want to guarantee your code execution on correct thread. For example:
DispatchQueue.main.async {
dispatchPrecondition(condition: .onQueue(DispatchQueue.global())) // will assert because we're executing code on main thread
}
In latest Swift 4.0 ~ 4.2, we can use Thread.current
See Returns the thread object representing the current thread of execution