Swift Concurrency Tips
If you add
@MainActor
attribute to a function, it is not the same as wrapping the whole method inDispatchQueue.main.async
. If your method containsawait
keyword, the code will be split into two pieces – one beforeawait
and one afterawait
, and as mentioned before, once the method hitsawait
another pending call can start running even before the first one is finished.[…]
You should remember to always mark a code with
@MainActor
if you require the Main Thread. You shouldn’t make implicit assumptions. The problem is when you suddenly start addingasync-await
to an existing project that was implemented without using Swift Concurrency. You can easily get into trouble if you don’t pay enough attention when mixing old code withasync-await
.[…]
First of all, you should avoid long-running synchronous work in
Task
. For that, you should use GCD and custom queues. This way you will prevent blocking unintentionally someTaskPriority
. However, you should be also aware that having too many custom queues is not recommended because of possible Thread Explosion. Therefore, you may try usingOperationQueue
to limit concurrency.[…]
[If] you test your code on a simulator each
TaskPriority
will be limited to only 1 task running at the same time.
Previously:
Update (2022-11-09): Rob Jonson:
Another misleading article saying @MainActor guarantees a function runs on the main thread. It doesn’t. It only guarantees that code you compile will call on the main thread. System callbacks can still call this function on any thread. Apple should document/emphasise this.
3 Comments RSS · Twitter
So did they actually simplify concurrency with all these new features or did they just shuffle the deck and make it easy to write incorrect code just in a different way?
mea culpa: after chastising Wojciech for overstating what @MainActor guarantees, I overstated the guarantee myself!
I said :
> It only guarantees that code you compile will call on the main thread.
Even that isn't necessarily true!
https://blog.hobbyistsoftware.com/2022/11/five-ways-to-break-swift-concurrency/
@iamaperson From reading all of this, several of the issues have to do with the very nature of async-await, like being careful about assumptions about (1) the thread you are running on, and (2) the need to be re-entrant (including on the same thread!). The issue with main thread enforcement really looks like a "bug" (or at best a leaky abstraction). Most problematic are performance issues coming from potential thread explosions, since they are "inherited" from GCD... Otherwise, apparently, we are spared race conditions and deadlocks. I am sure I am missing some stuff, but that's my takeaway in very short.