Swift6 并发和 NSBundleResourceRequest

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

我很难理解为什么我的代码不能在 Swift6 模式下工作。

这是一个简约的例子:

final actor ODRRequest {
    let request = NSBundleResourceRequest(tags: ["bla"])

    func startRequest() {
        Task {[unowned self] in
            let available = await request.conditionallyBeginAccessingResources()
            if available {
                updateState(.available)
            }
        }
    }
}

这无法告诉我“发送‘NSBundleResourceRequest’类型的参与者隔离值以及稍后访问非隔离上下文的风险会导致数据争用”。

同时,这也没有问题:

private func startRequest() {
    request.conditionallyBeginAccessingResources {[unowned self]  available in
        Task {
            if available {
                await updateState(.available)
            }
        }
    }
}

任何人都可以向我解释为什么编译器抱怨第一个实现但不抱怨第二个实现?这些功能应该是相同的。

swift concurrency swift-concurrency swift6
1个回答
0
投票

我认为您可以做您想做的事情 - 即,通过使用简单的

class
而不是
actor
,将您的请求和与其对话的方法移至单个实例中;这是草图:

final class ODRRequest {
    var request: NSBundleResourceRequest?

    func startRequest() async {
        let request = NSBundleResourceRequest(tags: ["bla"])
        let available = await request.conditionallyBeginAccessingResources()
        if available {
            // do stuff
        }
        self.request = request
    }

    func beginAccessing() async throws {
        try await request?.beginAccessingResources()
        /// do stuff if we get here
    }

    func stopAccessing() {
        request?.endAccessingResources()
        request = nil
    }
}

它可以在我的机器上编译,但我不认为我以某种方式欺骗了编译器。

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