在委托外观中使用 swift actor

问题描述 投票:0回答:1

我正在阅读此博客,因为我有类似的用例:https://kelvas09.github.io/blog/posts/closure-delegate-to-async/

我注意到以下片段:

actor BluetoothLEScanWrapper {

enum BluetoothLEScanError: Error {
    case bluetoothNotAvailable
}

private let bluetoothLEDelegate: BluetoothLEDelegate = BluetoothLEDelegate()
private var activeTask: Task<[BluetoothLEDevice], Error>?

func scan(for seconds: Double = 3.0) async throws -> [BluetoothLEDevice] {

    if let existingTask = activeTask {
        return try await existingTask.value
    }

    let task = Task<[BluetoothLEDevice], Error> {
        guard bluetoothLEDelegate.bluetoothIsOn else {
            activeTask = nil
            throw BluetoothLEScanError.bluetoothNotAvailable
        }

        self.bluetoothLEDelegate.central.scanForPeripherals(withServices: nil)

        try await Task.sleep(nanoseconds: (UInt64(seconds) * 1_000_000_000))

        let devices = bluetoothLEDelegate.foundPeripheral.compactMap { BluetoothLEDevice(peripheral: $0) }

        bluetoothLEDelegate.central.stopScan()
        bluetoothLEDelegate.foundPeripheral = []

        activeTask = nil

        return devices
    }

    activeTask = task

    return try await task.value

}
...

作者特别呼吁注意演员的使用。据我了解,这是为了避免与

activeTask
发生数据竞争,以防
scan()
被重复调用。我的理解正确吗?感谢您的帮助。

ios swift async-await concurrency actor
1个回答
0
投票

是的,你是对的。 Actor 用于防止数据争用。请参阅使用 Swift Actor 保护可变状态使用 Swift Concurrency 消除数据争用

© www.soinside.com 2019 - 2024. All rights reserved.