hachyderm.io is one of the many independent Mastodon servers you can use to participate in the fediverse.
Hachyderm is a safe space, LGBTQIA+ and BLM, primarily comprised of tech industry professionals world wide. Note that many non-user account types have restrictions - please see our About page.

Administered by:

Server stats:

9.7K
active users

Mike Apurin

In Swift 6, the sink closure inherits MainActor isolation from the VC, and the compiler helpfully inserts a dynamic check that helpfully crashes the app at runtime. (Check out the helpful backtrace!)

Is the expected solution to audit all the closures in the project and to explicitly mark the offending ones, e.g. .sink { @\Sendable in ... } ?

@mattiem I get that it's needed to plug isolation leaks -- but forcing a crash seems like too much :(

With this example particularly, I’m not even explicitly using Concurrency, it just makes perfectly safe code crash.

@auramagi Is this being compiled with Swift 6 mode?

@mattiem Yeah. With Swift 5 mode, it runs without a problem.

@auramagi Yeah this has been a problem for a number of people, and I expect it will come up more.

You are using concurrency though, both a nonisolated and a global queue. Those things count!

@mattiem nonisolated method here is not relevant -- the assert happens before anything in the closure is run -- and I'd argue that a DispatchQueue is not part of Swift Concurrency 🙃

I am using a MainActor though, just very indirectly.

@auramagi Nonisolated is super relevant because this is a serious bug without it!

I get what you are saying, but Swift concurrency is a language feature. The core problem, in my opinion, was Combine was not updated and that’s bananas.

@mattiem
> Combine was not updated and that’s bananas.

+1

@auramagi It's not much help, but: Passing the function reference directly to sink instead of creating a closure (e.g. `.sink(receiveValue: self.doAThing)`) also lets you avoid the crash.

@auramagi heh @sendable in closures saved me from a few crashes. Is this really obvious though to you on first glance? I’m still getting this into my muscle memory but whew now we know

@romy I feel like it's not too hard to understand what's happening -- closures just inherit the isolation, and Swift is not happy when it doesn’t match in runtime. But crashing on this seems too harsh, and it's almost impossible to catch when you're calling code you don't own (e.g. Combine here). 🫠

@auramagi 🙈🙈🙈🙈 I’m actually starting to like strict concurrency lately 🥹 it just takes getting used to especially rigging legacy code !!! Have you used the new concurrency instruments yet

@romy I think I like it too, but I'm hoping the Swift language folks round off some rough edges in the future 🤞
I remember using concurrency instruments only once -- when my definitely wrong custom actor executor started crashing on a new iOS version