Skip to content

Instantly share code, notes, and snippets.

@Diggory
Created December 14, 2020 16:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Diggory/da2e82f07efae056f9fe3b9630101c11 to your computer and use it in GitHub Desktop.
Save Diggory/da2e82f07efae056f9fe3b9630101c11 to your computer and use it in GitHub Desktop.
Actors in Swift
/// https://github.com/DougGregor/swift-evolution/blob/actors/proposals/nnnn-actors.md
// Swift Concurrency experiments
import Foundation
// A simple Actor which has both mutable and immutable value-type stored properties
actor class AnActor {
let immutable = "I will never chage"
var mutable = "I can change"
var timesChanged = 0
// Synchronous therefore Actor-Isolated (cannot be called from without the instance.)
func test() {
print("Hello from the Actor.")
print("Changing mutable property")
changeMutable()
}
// Async so can be called from without the instance, but therefore must be awaited upon when called.
func testAsync() async {
test()
}
func changeMutable(_ newVal : String = "I have changed") {
timesChanged = timesChanged + 1
mutable = newVal + " \(timesChanged) times"
}
}
// An actor singleton to act as the Global Actor
actor class TheGlobalActor {
static let shared = TheGlobalActor()
private init() { }
func test() {
print("I am the global actor, I don't do much above the surface...")
}
}
@globalActor
struct MainContainer {
static let shared = TheGlobalActor.shared
let simpleActor = AnActor()
func main() async {
print("Hello main")
print("simpleActor.immutable \(simpleActor.immutable) : simpleActor.mutable \(simpleActor.mutable)")
// Should fail, but doesn't? test() isn't marked as async. Maybe auto-async magic?
await simpleActor.test();
print("simpleActor.immutable \(simpleActor.immutable) : simpleActor.mutable \(simpleActor.mutable)")
// Should be OK, as this method is a convenience async one.
await simpleActor.testAsync()
print("simpleActor.immutable \(simpleActor.immutable) : simpleActor.mutable \(simpleActor.mutable)")
}
}
// Non-globalActor access to an actor?
let badActor = AnActor()
// Should be possible as it's immutable
print("badActor.immutable: \(badActor.immutable)")
// Should not be possible as it's mutable
print("badActor.mutable: \(badActor.mutable)")
// GlobalActor access to the actor
@MainContainer
let mainContainer = MainContainer()
// This allows us to call async from a synchronous-only place
_ = Task.runDetached(operation: mainContainer.main)
let runLoop = RunLoop.current
let distantFuture = Date.distantFuture
/// Set this to false when we want to exit the app...
var shouldKeepRunning = true
while shouldKeepRunning == true &&
runLoop.run(mode:.default, before: distantFuture) {}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment