Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check current thread in Swift 3?

People also ask

What is the main thread in Swift?

The main thread is the one that starts our program, and it's also the one where all our UI work must happen. However, there is also a main queue, and although sometimes we use the terms “main thread” and “main queue” interchangeably, they aren't quite the same thing.

How we can ensure execute code in the main thread?

If you're on a background thread and want to execute code on the main thread, you need to call async() again. This time, however, you do it on DispatchQueue. main , which is the main thread, rather than one of the global quality of service queues.


Looks like it's simply Thread.isMainThread in Swift 3.


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

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)

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


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