Actor-isolated 属性 无法传递 'inout' 到 'async' 函数调用

Actor-isolated property cannot be passed 'inout' to 'async' function call

我是 Swift 并发的新手(我想和大多数人一样),我 运行 遇到编译器错误,我不知道该怎么办。


struct Thing {
  var counter = 0
  mutating func increment() async {
    counter += 1
  }
}

class Controller: UIViewController {
  var thing = Thing()
  
  func mutate() async {
    await thing.increment()
    print(thing.counter)
  }
}

let c = Controller()
Task {
  await c.mutate()
}

mutate() 函数的第一行给出了以下错误。 Actor-isolated property 'thing' cannot be passed 'inout' to 'async' function call

如果我只是从 class 而不是 UIViewController 继承,一切正常,但我需要这里的控制器,所以我需要弄清楚如何在特定的上下文中使它工作。

我认为问题出在 Thingstruct。结构上的 mutating 函数会将新值分配给 Controller 上的 thing 属性。为了使其工作,thing 在对 thing.increment().

的调用中被视为 inout 参数

如果你把事情做成 actor 而不是 struct 那么 increment() 就不需要是 mutating func 所以 thing 不会'不被视为 inout 参数。


一个可能的解决方法是先复制结构,然后在副本上调用变异函数,然后将其存储回控制器中的 属性。

func mutate() async {
    var thing = self.thing
    await thing.increment()
    self.thing = thing
    
    print(thing.counter)
}

这是一个问题的原因是 UIViewControllers 现在都是演员,所以属性被认为是孤立的演员。有一个 nonisolated 关键字,但它不能应用于存储的属性,因此它在这里似乎没有帮助。

如果将控制器更改为 actor,则错误消息会稍微改变一下。

error: cannot call mutating async function 'increment()' on actor-isolated property 'thing'
        await thing.increment()
                    ^