I have an older project that was created before Xcode 26.2.
In Xcode versions prior to 26.2, there was no Swift Compiler – Concurrency build setting.
With those older versions, the following behavior occurs: a nonisolated function executes off the main thread.
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
run()
}
private func run() {
Task {
await runInMainThread()
}
}
func runInMainThread() async {
print(">>>> IN runInMainThread(), Thread.isMainThread \(Thread.isMainThread)")
await runInBackgroundThread()
}
private nonisolated func runInBackgroundThread() async {
print(">>>> IN runInBackgroundThread(), Thread.isMainThread \(Thread.isMainThread)")
}
}
Output:
>>>> IN runInMainThread(), Thread.isMainThread true
>>>> IN runInBackgroundThread(), Thread.isMainThread false
However, starting with Xcode 26.2, Apple introduced the Swift Compiler – Concurrency settings.
When running the same code with the default configuration:
Approachable Concurrency = Yes
Default Actor Isolation = MainActor
This is the output
Output:
>>>> IN runInMainThread(), Thread.isMainThread true
>>>> IN runInBackgroundThread(), Thread.isMainThread true
the nonisolated function now executes on the main thread.
This raises the following questions:
-
What is the correct Swift Compiler – Concurrency configuration if I want a
nonisolatedfunction to run off the main thread? -
Is
nonisolatedstill an appropriate way to ensure code runs on a background thread?
Is nonisolated still an appropriate way to ensure code runs on a background thread?
Yes and no.
There are a couple of Swift Evolution proposals that describe this change in detail:
- SE-0461 Run nonisolated async functions on the caller's actor by default
- SE-0466 Control default actor isolation inference
And, as you’ve noticed, there are Xcode build settings that affect this stuff. So, you have a couple of options:
- You can tweak your build settings and leave your code as is.
- Or you can move forward to the new build settings and tweak your code.
I generally favour the second option, but I can understand folks preferring the first option, especially when wrangling a large project.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"