如何解决Swift警告:主actor隔离属性不能从可发送闭包中进行改变。

3

我有一个用Swift开发的应用程序,它运行良好。最近的Swift版本现在在我的代码的某些部分上显示警告,指示这在Swift 6中不起作用。我不确定解决这个问题的最佳方法。以下是摘录:

@MainActor class ViewModel: ObservableObject {

    private var _http_last_error: String = "--"

    func fetch_cpuinfo() {
        var request = URLRequest(url: _cpuinfo_url!)
        request.httpMethod = "GET"

        // create a dataTask, which includes a closure to process the response
        let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
            // Check for Error
            if let error = error {
                self._http_last_error = error.localizedDescription // WARNING HERE
                return
            }
        }
        task.resume()
    }
}

具体警告是“主演员隔离属性'_http_last_error'无法从可发送闭包中进行突变;这是Swift 6中的错误”。我理解为什么这是个问题;在此任务块中的代码将稍后执行,并且没有对写入的变量进行保护。但我不知道最好的保护方法。
1个回答

5
请使用新的 async/await 版本的 dataTask
func fetch_cpuinfo() {
    var request = URLRequest(url: _cpuinfo_url!)
    request.httpMethod = "GET"

    Task {
        do {
            let (data, response) = try await URLSession.shared.data(for: request)
            // handle data and response...
        } catch {
            self._http_last_error = error.localizedDescription
        }
    }
}

或者更好的是将整个函数变成异步的。

func fetch_cpuinfo() async {
    var request = URLRequest(url: _cpuinfo_url!)
    request.httpMethod = "GET"

    do {
        let (data, _) = try await URLSession.shared.data(for: request)
        // handle data and response...
    } catch {
        self._http_last_error = error.localizedDescription
    }
} 

我还建议您遵循Swift的常见命名惯例,使用驼峰式命名法,而不是下划线字符,例如fetchCpuInfo()httpLastError - Joakim Danielson
谢谢,Joakim,这确实非常有帮助。一个问题:在你的示例中,变量error是如何/在哪里声明的?这是隐含在catch中吗? - John S
是的,在catch中它是隐含的。 - Joakim Danielson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接