#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, а не на детали реализации.