18.4 C
New York
Monday, March 10, 2025

Fixing “Worth of non-Sendable sort accessed after being transferred; later accesses might race;” – Donny Wals


Revealed on: August 23, 2024

When you begin migrating to the Swift 6 language mode, you may most probably activate strict concurrency first. As soon as you have performed this there shall be a number of warings and errors that you will encounter and these errors will be complicated at instances.

I am going to begin by saying that having a strong understanding of actors, sendable, and information races is a big benefit once you need to undertake the Swift 6 language mode. Just about the entire warnings you may get in strict concurrency mode will let you know about potential points associated to working code concurrently. For an in-depth understanding of actors, sendability and information races I extremely advocate that you simply check out my Swift Concurrency course which can get you entry to a sequence of movies, workout routines, and my Sensible Swift Concurrency e book with a single buy.

WIth that out of the way in which, let’s check out the next warning that you simply may encounter in your undertaking:

Worth of non-Sendable sort ‘MyType’ accessed after being transferred; later accesses might race;

For instance, the next code produces such an error:

var myArray = [Int]()

Activity {
  // Worth of non-Sendable sort '@remoted(any) @async @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()>' accessed after being transferred; later accesses might race;
  myArray.append(1)
}

myArray.append(2)

Xcode provides somewhat steering as to what that error is telling us:

Entry can occur concurrently

In different phrases, the compiler is telling us that we’re accessing myArray after we have “transferred” that property to our Activity. You possibly can see how we’re appending to the array each within the duty in addition to outdoors of it.

Swift is telling us that we’re probably inflicting information races right here as a result of our append on myArray after the duty may really collide with the append inside of the duty. When this occurs, we now have a knowledge race and our code would crash.

The repair right here could be to explicitly make a replica for our activity when it is created:

Activity { [myArray] in
  var myArray = myArray
  myArray.append(1)
}

This eliminates our information race potential however it’s additionally not likely reaching our aim of appending to the array from within the duty.

The repair right here may very well be one in all a number of approaches:

  1. You possibly can wrapp your array in an actor to make sure correct isolation and synchronization
  2. You possibly can rework your strategy fully
  3. International actors may very well be helpful right here relying on the construction of your code

In the end, most strict concurrency associated points do not have a single resolution that works. It is all the time going to require a case-by-case evaluation of why a sure error seems, and from there you need to work out an answer.

On this case, we’re taking a mutable object that we’re mutating from inside a activity in addition to proper after the place we have outlined the duty. The compiler is warning us that that may most probably trigger a knowledge race and you will want to find out which resolution works for you. My first try at fixing this could be to wrap the mutable state in an actor to verify we obtain correct isolation and stop future information races.

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles