20

I try to check the actor's behavior. This is a new feature provided by Swift5.5.

I've created a playground with an example code from the official documentation swift.org:

    import Foundation
    
    actor TemperatureLogger {
        let label: String
        var measurements: [Int]
        private(set) var max: Int

        init(label: String, measurement: Int) {
            self.label = label
            self.measurements = [measurement]
            self.max = measurement
        }
    }

    let logger = TemperatureLogger(label: "Outdoors", measurement: 25)
    print(await logger.max)
    // Prints "25"

But my compiler fails on this example:

errors

Swift Compiler Error:

'await' in a function that does not support concurrency

Actor-isolated property 'max' can only be referenced from inside the actor

So how to access an actor-isolated property?

Maybe it's a bug in the compiler or in the example code?

Xcode Version 13.0 beta (13A5154h) Swift Version 5.5

George
  • 25,988
  • 10
  • 79
  • 133
Denis Kreshikhin
  • 8,856
  • 9
  • 52
  • 84

1 Answers1

17

Put the access in an Task block. Actor isolated properties synchronise and enforce exclusive access through the "cooperative thread pool" and could suspend, so this needs to run asynchronously.

let logger = TemperatureLogger(label: "Outdoors", measurement: 25)
Task {
    print(await logger.max)
    // Prints "25"
}
Bradley Mackey
  • 6,777
  • 5
  • 31
  • 45
  • This just gives me `'async(priority:operation:)' is deprecated: \`async\` was replaced by \`Task.init\` and will be removed shortly.` – Ky - Jul 31 '21 at 06:16
  • 6
    @KyLeggiero See updated answer. Creation of an async task was changed from `async` to `Task` in the most recent Swift 5.5 beta, as the error message you have got clearly shows. Perhaps an edit to the answer would have been more helpful than a downvote :) – Bradley Mackey Jul 31 '21 at 08:47
  • 1
    Except this doesnt work if you need the result in the current context... –  Dec 13 '21 at 08:42
  • 1
    @Era Do you mean from a synchronous context? If so then yes, you'll need to make sure your 'context' is also asynchronous or use a callback or similar to return the results. It would be a violation of the asynchronous runtime model to block synchronously and wait for a result, for example. – Bradley Mackey Dec 13 '21 at 15:17