Alamofire RequestRetrier,在主操作队列上调用完成块可以吗?

Posted

技术标签:

【中文标题】Alamofire RequestRetrier,在主操作队列上调用完成块可以吗?【英文标题】:Alamofire RequestRetrier, is it ok to call the completion block on the main operation queue? 【发布时间】:2021-12-17 18:09:54 【问题描述】:

我一直想知道是否从主队列上的请求重试调用完成块可以,因为函数调用是在 session.rootQueue 上进行的

func retry(_ request: Request, for session: Session, dueTo error: Error, completion: @escaping (RetryResult) -> Void) 
    
        OperationQueue.main.addOperation  [weak self] in
            
            guard let self = self else 
                completion(.doNotRetryWithError(e))
                return
            
            self.handleError(e, completion: completion)
            
        
        
    
    

文档没有明确说明,但如果我没记错的话,通常会在函数调用所在的队列中调用完成块

public protocol RequestRetrier 
    /// Determines whether the `Request` should be retried by calling the `completion` closure.
    ///
    /// This operation is fully asynchronous. Any amount of time can be taken to determine whether the request needs
    /// to be retried. The one requirement is that the completion closure is called to ensure the request is properly
    /// cleaned up after.
    ///
    /// - Parameters:
    ///   - request:    `Request` that failed due to the provided `Error`.
    ///   - session:    `Session` that produced the `Request`.
    ///   - error:      `Error` encountered while executing the `Request`.
    ///   - completion: Completion closure to be executed when a retry decision has been determined.
    func retry(_ request: Request, for session: Session, dueTo error: Error, completion: @escaping (RetryResult) -> Void)

所以我的问题是,应该在哪个队列上调用完成?

【问题讨论】:

【参考方案1】:

是的,它是安全的,因为调用您的重试器的内部实现会立即回调 Alamofire 的 rootQueue

从 Alamofire 5.4.4 开始:

retrier.retry(request, for: self, dueTo: error)  retryResult in
    self.rootQueue.async 
        guard let retryResultError = retryResult.error else  completion(retryResult); return 

        let retryError = AFError.requestRetryFailed(retryError: retryResultError, originalError:
error)
        completion(.doNotRetryWithError(retryError))
    

【讨论】:

as the internal implementation - 这可能会发生变化,未来可以完全重写实现。我们应该依赖 API 文档,而不是实现细节。

以上是关于Alamofire RequestRetrier,在主操作队列上调用完成块可以吗?的主要内容,如果未能解决你的问题,请参考以下文章

Swift 3 的 ObjectMapper 和 Alamofire 问题 Alamofire 4 的 Alamofire 版本

导入 Alamofire 3.4 - 没有这样的模块“Alamofire”

Alamofire:responseSerializationFailed(Alamofire.AFError.ResponseSerializationFailureReason.inputData

出现错误:使用 Alamofire.playground 时没有这样的模块“Alamofire”

var 请求:Alamofire.Request?使用未声明类型的 Alamofire

值:(failure(Alamofire.AFError.explicitlyCancelled)) 使用 Alamofire 发布者时