# Confused about concurrency problem presented in wwdc24 video

**URL:** <https://forums.swift.org/t/confused-about-concurrency-problem-presented-in-wwdc24-video/74118>\
**Category:** Using Swift\
**Tags:** concurrency\
**Created:** [August 23, 2024, 2:29am UTC](https://forums.swift.org/t/confused-about-concurrency-problem-presented-in-wwdc24-video/74118 "2024-08-23T02:29:03Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![BitByAVampire](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/bitbyavampire/32/36297_2.png) [@BitByAVampire](https://forums.swift.org/u/BitByAVampire)\
**Post date:** [August 23, 2024, 2:29am UTC](https://forums.swift.org/t/confused-about-concurrency-problem-presented-in-wwdc24-video/74118/1 "2024-08-23T02:29:03Z")

</div>

In [What’s new in Xcode 16 - WWDC24 - Videos - Apple Developer](https://developer.apple.com/videos/play/wwdc2024/10135/) starting at **10:22** , the guy talks about a imagined scenario involving an issue of performing I/O on the main thread. At the end of that section, he says that the `task` modifier is inheriting the `mainactor` context from the swiftui view, and somehow the `robotAVVideoPlayer` function is inheriting that (im guessing that its because that function is inside the same swiftui view struct so they both get the same context?), and to resolve the problem he described, he will make that function `nonisolated`.

The last part I definitely don't get: how does making the function `nonisolated` ensure that the `AVPlayer` is not called on main thread? Doesnt nonisolated just mean that anybody can call it from anywhere, i.e. it says nothing about the thread?

---

<div class="post-metadata">

**Author:** ![QuinceyMorris](https://avatars.discourse-cdn.com/v4/letter/q/d26b3c/32.png) [@QuinceyMorris](https://forums.swift.org/u/QuinceyMorris)\
**Post date:** [August 23, 2024, 5:41pm UTC](https://forums.swift.org/t/confused-about-concurrency-problem-presented-in-wwdc24-video/74118/2 "2024-08-23T17:41:27Z")

</div>

No, `nonisolated` just means that it's not isolated to any actor — which of course isn't any kind of explanation.

To understand what's going on, you need to consider an additional piece of information: the function that's being marked `nonisolated` is an `async` function.

A non-isolated async function runs on a special non-actor asynchronous context, and that is similar to the non-main context that concurrent tasks use more generally in Swift. In particular, that's going to involve a non-main thread.

So, it's the combination of `nonisolated` and `async` that "forces" execution off the main thread.

---

<div class="post-metadata">

**Author:** ![BitByAVampire](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/bitbyavampire/32/36297_2.png) [@BitByAVampire](https://forums.swift.org/u/BitByAVampire)\
**Post date:** [August 23, 2024, 5:50pm UTC](https://forums.swift.org/t/confused-about-concurrency-problem-presented-in-wwdc24-video/74118/3 "2024-08-23T17:50:05Z")

</div>

Is there any documentation about this? What use case was there in mind when they designed this behaviour? It seems to me like it be easier to think about the code if non isolated async functions run on the same thread as if it were non isolated sync.

---

<div class="post-metadata">

**Author:** ![David\_Smith](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/david_smith/32/37508_2.png) [@David\_Smith](https://forums.swift.org/u/David_Smith)\
**Post date:** [August 23, 2024, 5:50pm UTC](https://forums.swift.org/t/confused-about-concurrency-problem-presented-in-wwdc24-video/74118/4 "2024-08-23T17:50:12Z")

</div>

Full details here [swift-evolution/proposals/0338-clarify-execution-non-actor-async.md at main · swiftlang/swift-evolution · GitHub](https://github.com/swiftlang/swift-evolution/blob/main/proposals/0338-clarify-execution-non-actor-async.md)

In short, `async` functions _always_ define where they run (which is the opposite of how systems like libdispatch work). `nonisolated` doesn't opt out of that, it just defines it as "the place where I run is not on any actor". In my opinion this is much easier to reason about because you never have to think "some async functions care about where they're called from and others don't", it's just "async functions never care about their caller".

---

<div class="post-metadata">

**Author:** ![tclementdev](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tclementdev/32/13398_2.png) [@tclementdev](https://forums.swift.org/u/tclementdev)\
**Post date:** [August 23, 2024, 8:04pm UTC](https://forums.swift.org/t/confused-about-concurrency-problem-presented-in-wwdc24-video/74118/5 "2024-08-23T20:04:40Z")

</div>

> [@David\_Smith](#):
>
> In my opinion this is much easier to reason about because you never have to think "some async functions care about where they're called from and others don't", it's just "async functions never care about their caller".

Which isn't true anymore because of isolated parameters with `#isolation`. I think this bugs everyone at first, and for good reasons. For example, non-sendable types are isolated to the domain where they are used but their async functions will hop to a different isolation. This is really strange behavior I think.

---

<div class="post-metadata">

**Author:** ![David\_Smith](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/david_smith/32/37508_2.png) [@David\_Smith](https://forums.swift.org/u/David_Smith)\
**Post date:** [August 23, 2024, 8:16pm UTC](https://forums.swift.org/t/confused-about-concurrency-problem-presented-in-wwdc24-video/74118/6 "2024-08-23T20:16:08Z")

</div>

> [@tclementdev](#):
>
> Which isn't true anymore because of isolated parameters with `#isolation`

Yeah, that does add some complexity unfortunately. I still think the rule of thumb is good to internalize, but thank you for noting the special case.

---

<div class="post-metadata">

**Author:** ![vns](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/vns/32/37396_2.png) [@vns](https://forums.swift.org/u/vns)\
**Post date:** [August 23, 2024, 9:05pm UTC](https://forums.swift.org/t/confused-about-concurrency-problem-presented-in-wwdc24-video/74118/7 "2024-08-23T21:05:19Z")

</div>

> [@tclementdev](#):
>
> For example, non-sendable types are isolated to the domain where they are used but their async functions will hop to a different isolation.

Wouldn’t the compiler prevent this? I think the only allowed way for non-Sendable types with isolated async functions to be used is if they always are called from one isolation, and other uses compiler forbids.

---

<div class="post-metadata">

**Author:** ![tclementdev](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tclementdev/32/13398_2.png) [@tclementdev](https://forums.swift.org/u/tclementdev)\
**Post date:** [August 23, 2024, 9:22pm UTC](https://forums.swift.org/t/confused-about-concurrency-problem-presented-in-wwdc24-video/74118/8 "2024-08-23T21:22:06Z")

</div>

The compiler will force developers to deal with warnings already which seems quite unfortunate at this point. The only thing that seems to make sense here is to use `#isolation` everywhere.

---

<div class="post-metadata">

**Author:** ![vns](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/vns/32/37396_2.png) [@vns](https://forums.swift.org/u/vns)\
**Post date:** [August 24, 2024, 6:40am UTC](https://forums.swift.org/t/confused-about-concurrency-problem-presented-in-wwdc24-video/74118/9 "2024-08-24T06:40:02Z")

</div>

I don't understand what you mean. I was referring to this part

> [@tclementdev](#):
>
> For example, non-sendable types are isolated to the domain where they are used but their async functions will hop to a different isolation.

Either with isolated parameter or without it, you won't be able to call different functions from different isolations on non-`Sendable` type. Consider this class

```swift
class NonSendable {
    var i = 0

    func inc() {
        i += 1
    }

    func dec(isolation: isolated (any Actor)? = #isolation) async {
        await Task.yield()
        i -= 1
    }
}

```

You wouldn't be then able to use it anywhere but in one isolation

```swift
@MainActor
struct Runner {
    let ns = NonSendable() 

    func run() async {
        ns.inc()
        await ns.dec() // ok, main isolation
    }
}

```

But we cannot alter it back and forth

```swift
extension Runner {
    actor Another {
    }
    
    func anotherRun() {
        let another = Another()
        ns.inc()
        await ns.dec(isolation: another) // error: potential data race
    }
}

```

> [@tclementdev](#):
>
> The only thing that seems to make sense here is to use `#isolation` everywhere.

I don't think we should abuse `#isolation`: it is great for library code in the first place and for generalized code in projects, but not for everything. Non-`Sendable` types with async methods are useful now as is thanks to region-based isolation:

```swift
Task.detached {
    let ns = NonSendable()
    ns.inc()
    await ns.dec() // ok, `ns` in disconnected region
}

```

---

<div class="post-metadata">

**Author:** ![tclementdev](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tclementdev/32/13398_2.png) [@tclementdev](https://forums.swift.org/u/tclementdev)\
**Post date:** [August 24, 2024, 7:23am UTC](https://forums.swift.org/t/confused-about-concurrency-problem-presented-in-wwdc24-video/74118/10 "2024-08-24T07:23:23Z")

</div>

I'm sorry but your response seems very academic and contrived to be in line with how the compiler works right now. In real world projects, you will find a lot of non-sendable types that cannot benefit from region based isolation, and inheritance is what makes sense there (and this is also how a lot of developers think it works at first).

---

<div class="post-metadata">

**Author:** ![vns](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/vns/32/37396_2.png) [@vns](https://forums.swift.org/u/vns)\
**Post date:** [August 24, 2024, 7:50am UTC](https://forums.swift.org/t/confused-about-concurrency-problem-presented-in-wwdc24-video/74118/11 "2024-08-24T07:50:06Z")

</div>

That’s _exactly_ how compiler works right now. You can run examples and see.

I say that from a very practical experience, and as much as I would love to have dynamic isolation for non-Sendable types with a greater support, having isolated parameters all over the place are significantly complicate the code, and are more academic. Instead, isolating types to a global actor(s) is much more practical and lead to an easier code.
