2

我正在将我的代码转换为使用 Swift 并发,我遇到了 Actor 的问题,我不知道如何正确修复它。

这是一个简单的演员:

actor MyActor {
    private var count = 0
    
    func increase() {
        count += 1
    }
}

在我需要更新actor的其他地方,我必须在并发上下文中调用它的函数:

Task {
    await myActor.increase()
}

那挺好的。但我不明白的是,如果演员increase像这样将函数作为闭包返回:

actor MyActor {
    private var count = 0
    
    func increase() -> () -> Void {
        {
            print("START")
            self.count += 1
            print("END")
        }
    }
}

在其他地方,我可以获得对返回的闭包的引用并在非并发上下文中自由调用它:

class ViewController: UIViewController {
    let actor = MyActor()

    var increase: (() -> Void)?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        Task {
            increase = await actor.increase()
        }
        
        DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
            let increase = self.increase
            
            DispatchQueue.concurrentPerform(iterations: 100) { _ in
                increase?()
            }
        }
    }
}

上面的代码将其打印到输出:

START
START
START
START
START
END
END
START
START
...

我不确定我是否正确理解或使用 Actor。Actor 保护其状态免受数据竞争的影响,但在这种情况下,它不会阻止这种情况。这是正确的行为吗?有没有办法解决它?

4

0 回答 0