Alamofire RequestRetrier, можно ли вызвать блок завершения в основной очереди операций?

#swift #alamofire #grand-central-dispatch

Вопрос:

Мне было интересно, можно ли вызвать блок завершения из повторной попытки запроса в основной очереди, так как вызов функции выполняется в сеансе.rootQueue

 func retry(_ request: Request, for session: Session, dueTo error: Error, completion: @escaping (RetryResult) -gt; 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) -gt; 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))  } }  

Комментарии:

1. as the internal implementation — это может быть изменено, реализация может быть полностью переписана в будущем. Мы должны полагаться на документацию API, а не на детали реализации.