9.5 C
New York
Tuesday, March 11, 2025

ios – What’s the level of `Sendable` protocol in Swift


As you stated, Sendable permits the compiler to cause about whether or not a worth is secure to ship throughout concurrency domains. That is very helpful, since you usually write code that sends issues throughout concurrency domains. The compiler can verify whether or not your code is secure or not. With out Sendable, the compiler will both must disallow any sending (overly restrictive), or permit all sendings (not secure).

From SE-0302:

Every actor occasion and structured concurrency process in a program represents an “island of single threaded-ness”, which makes them a pure synchronization level that holds a bag of mutable state. These carry out computation in parallel with different duties, however we would like the overwhelming majority of code in such a system to be synchronization free — constructing on the logical independence of the actor, and utilizing its mailbox as a synchronization level for its information.

As such, a key query is: “when and the way will we permit information to be transferred between concurrency domains?” Such transfers happen in arguments and outcomes of actor technique calls and duties created by structured concurrency, for instance.

A quite simple instance to reveal how helpful Sendable is, is:

func f(_ x: SomeType) {
    Activity {
        print(x)
    }
}

Is that this secure? That relies on whether or not values of SomeType are secure to ship to the highest stage Activity. If it isn’t secure to ship, you may find yourself with the worth of SomeType being shared between the Activity and wherever it initially got here from. For instance, if SomeType is a category with mutable properties, this may trigger a race:

func g() {
    let x = SomeType()
    f(x) // the duty that f creates may run concurrently with the subsequent line!
    x.someProperty = "some new worth"
}

If SomeType is Sendable, then the compiler can permit the primary code snippet to compile.


Right here is one other instance from SE-0302:

actor SomeActor {
  // async capabilities are usable *inside* the actor, so this
  // is alright to declare.
  func doThing(string: NSMutableString) async {}
}

// ... however they can't be referred to as by different code not protected
// by the actor's mailbox:
func f(a: SomeActor, myString: NSMutableString) async {
  // error: 'NSMutableString' might not be handed throughout actors;
  //        it doesn't conform to 'Sendable'
  await a.doThing(string: myString)
}

doThing is remoted to the actor, and the actor may retailer the string handed to doThing in considered one of its properties. After which you find yourself with a NSMutableString being shared between the actor and whoever initially owns it.

If we use String as a substitute of NSMutableString, this code is secure as a result of String is Sendable. String is copy-on-write, so the actor modifying it is not going to have an effect on the whoever owns it initially.

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles