SWIFT 任务延续误用:泄露了它的延续
SWIFT TASK CONTINUATION MISUSE: leaked its continuation
我正在使用以下函数通过 Alamofire 执行获取请求:
func afRequest(url: URL) async throws -> Data {
try await withCheckedThrowingContinuation { continuation in
// timeoutInterval is in seconds
AF.request(url, method: .get, requestModifier: { [=11=].timeoutInterval = 10 }).validate(statusCode: 200..<600).responseData { response in
if let data = response.data {
continuation.resume(returning: data)
return
}
guard case let .failure(error) = response.result else { return }
switch error {
case .invalidURL(let url):
print("Invalid URL: \(url) - \(error.localizedDescription)")
continuation.resume(throwing: error)
}
}
}
}
我特意将超时设置为 10 秒来进行测试。所以错误是"The request timed out."
。之后我得到这个错误:
SWIFT TASK CONTINUATION MISUSE: afRequest(url:) leaked its continuation!
我正在查看 this post,但不清楚他们完成了什么或解决方案。减轻这种泄漏的正确方法是什么?
编辑:
上面的部分我是这样切换的,但还是一样:
if case let .failure(error) = response.result {
switch error {
case .invalidURL(let url):
...
continuation.resume(throwing: error)
return
编辑 2 - 这是错误的新处理方式,但还是一样:
func afRequest(url: URL) async throws -> Data {
try await withCheckedThrowingContinuation { continuation in
// timeoutInterval is in seconds
AF.request(url, method: .get, requestModifier: { [=14=].timeoutInterval = .infinity }).validate(statusCode: 200..<600).responseData { response in
if let data = response.data {
continuation.resume(returning: data)
return
}
if case let .failure(error) = response.result {
switch error {
case .invalidURL(let url):
print("Invalid URL: \(url) - \(error.localizedDescription)")
// There are more cases...
continuation.resume(throwing: error)
return
}
}
else {
continuation.resume(throwing: Error.self as! Error)
return
}
}
}
}
你的守卫正在捕获一个案例,而不是调用继续。您需要从所有分支调用延续(例如 continuation.resume(...)
),以免泄漏。
这个早期 return
导致了这个问题
guard case let .failure(error) = response.result else { return }
在您的示例中,您需要决定如何处理 response.data
为零和 response.result
为成功,然后更新您的 guard
以适当地调用 continuation.resume(...)
。
我正在使用以下函数通过 Alamofire 执行获取请求:
func afRequest(url: URL) async throws -> Data {
try await withCheckedThrowingContinuation { continuation in
// timeoutInterval is in seconds
AF.request(url, method: .get, requestModifier: { [=11=].timeoutInterval = 10 }).validate(statusCode: 200..<600).responseData { response in
if let data = response.data {
continuation.resume(returning: data)
return
}
guard case let .failure(error) = response.result else { return }
switch error {
case .invalidURL(let url):
print("Invalid URL: \(url) - \(error.localizedDescription)")
continuation.resume(throwing: error)
}
}
}
}
我特意将超时设置为 10 秒来进行测试。所以错误是"The request timed out."
。之后我得到这个错误:
SWIFT TASK CONTINUATION MISUSE: afRequest(url:) leaked its continuation!
我正在查看 this post,但不清楚他们完成了什么或解决方案。减轻这种泄漏的正确方法是什么?
编辑:
上面的部分我是这样切换的,但还是一样:
if case let .failure(error) = response.result {
switch error {
case .invalidURL(let url):
...
continuation.resume(throwing: error)
return
编辑 2 - 这是错误的新处理方式,但还是一样:
func afRequest(url: URL) async throws -> Data {
try await withCheckedThrowingContinuation { continuation in
// timeoutInterval is in seconds
AF.request(url, method: .get, requestModifier: { [=14=].timeoutInterval = .infinity }).validate(statusCode: 200..<600).responseData { response in
if let data = response.data {
continuation.resume(returning: data)
return
}
if case let .failure(error) = response.result {
switch error {
case .invalidURL(let url):
print("Invalid URL: \(url) - \(error.localizedDescription)")
// There are more cases...
continuation.resume(throwing: error)
return
}
}
else {
continuation.resume(throwing: Error.self as! Error)
return
}
}
}
}
你的守卫正在捕获一个案例,而不是调用继续。您需要从所有分支调用延续(例如 continuation.resume(...)
),以免泄漏。
这个早期 return
导致了这个问题
guard case let .failure(error) = response.result else { return }
在您的示例中,您需要决定如何处理 response.data
为零和 response.result
为成功,然后更新您的 guard
以适当地调用 continuation.resume(...)
。