How to check current thread in Swift 3?
IosMultithreadingSwift3NsthreadIos Problem Overview
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()
Ios Solutions
Solution 1 - Ios
Looks like it's simply Thread.isMainThread
in Swift 3.
Solution 2 - Ios
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.
Solution 3 - Ios
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 { ... }
Solution 4 - Ios
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)
Solution 5 - Ios
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
}
Solution 6 - Ios
Swift 5+
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
Solution 7 - Ios
In latest Swift 4.0 ~ 4.2, we can use Thread.current
See Returns the thread object representing the current thread of execution