Alamofire源码学习

Alamofire最基本的使用方法:

AF.request("https://httpbin.org/get")

AF

AF其实是一个枚举类

Global namespace containing API for the default Session instance.

request方法的源码:

public static func request(_ url :       URLConvertible,
                           method :      HTTPMethod = .get,
                           parameters :  Parameters ? = nil,
                           encoding :    ParameterEncoding = URLEncoding.default,
                           headers :     HTTPHeaders ? = nil,
                           interceptor : RequestInterceptor ? = nil)->DataRequest {
    return Session.default.request(url,
                                   method: method,
                                   parameters: parameters,
                                   encoding: encoding,
                                   headers: headers,
                                   interceptor: interceptor)
}

先看传进来的参数,除了url之外其他参数都有默认值。

  • URLConvertible

url的类型是URLConvertible,这其实是一个协议,类似于Java的抽象类:

public protocol URLConvertible {
    /// Returns a `URL` from the conforming instance or throws.
    ///
    /// - Returns: The `URL` created from the instance.
    /// - Throws:  Any error thrown while creating the `URL`.
    func asURL() throws -> URL
}

提供了一个返回URL的方法。通过扩展让StringURLURLComponents都实现了该协议,也就是我们传进来的url只要是这三种类型的都可以。

extension String: URLConvertible {
...
extension URL: URLConvertible {
...
extension URLComponents: URLConvertible {
...
  • HTTPMethod

HTTPMethod就是一个定义请求方法的枚举类。

  • Parameters

Parameters就是字典类型的别名:

public typealias Parameters = [String: Any]

typealias用来定义别名

  • ParameterEncoding

ParameterEncoding也是一个协议,它的作用相当于AFNetwork的AFURLRequestSerialization。有两个结构体实现了该协议:URLEncodingJSONEncoding。这里默认值是URLEncoding.default

  • HTTPHeaders

HTTPHeaders是结构体:

public struct HTTPHeaders {
    private var headers: [HTTPHeader] = []
    ...

HTTPHeaders用一个数组保存headers,数组元素是HTTPHeader

更新headers的方法:

public mutating func update(_ header : HTTPHeader) {
    guard let index = headers.index(of: header.name) else {
        headers.append(header)
        return
    }

    headers.replaceSubrange(index ... index, with: [header])
}

先判断是否已经存在该header,如果没有则append新的,否则replaceSubrange进行替换。

headers.index(of: header.name)是扩展里面定义的方法:

extension Array where Element == HTTPHeader {
    /// Case-insensitively finds the index of an `HTTPHeader` with the provided name, if it exists.
    func index(of name: String) -> Int? {
        let lowercasedName = name.lowercased()
        return firstIndex { $0.name.lowercased() == lowercasedName }
    }
}

这种扩展只给元素为特定类型的Array增加方法。

  • RequestInterceptor

RequestInterceptor请求拦截器,有点像OkHttp的东西,后面再看有什么用。

Session

AF的request方法实际调用了Session.default的request方法。

public static let `default` = Session()

defaultSession的一个单例。这里default用单引号包围起来是因为default是Swift的关键字,所以不能直接用来命名。

Session有一个初始化方法加了一个convenience字段。

在Swift中类的实例在初始化的时候必须给所有成员变量都赋上初始值,Swift提供了两种初始化方式designated initializersconvenience initializers

designated initializers是主要的初始化方法,类似Object-C里面的NS_DESIGNATED_INITIALIZER宏。一般来说designated initializer只有一个,designated initializer负责调用父类的初始化方法,它要保证执行完后所有的属性都被赋值。

designated initializersconvenience initializers之间的规则:

  • 1、designated initializer必须调用父类的designated initializer;
  • 2、convenience initializer必须调用本类的其他初始化方法;
  • 3、convenience initializer最终必须调用到designated initializer

类的初始化方法在调父类的初始化方法之前,必须初始化完自己所有的成员变量。相反,如果是调用自己的其他初始化方法,则必须在调用完成后再初始化自己的成员变量。

看看Session的初始化方法:

public convenience init(configuration :            URLSessionConfiguration = URLSessionConfiguration.af.default,
                        delegate :                 SessionDelegate = SessionDelegate(),
                        rootQueue :                DispatchQueue = DispatchQueue(label: "org.alamofire.session.rootQueue"),
                        startRequestsImmediately : Bool = true,
                        requestQueue :             DispatchQueue ? = nil,
                        serializationQueue :       DispatchQueue ? = nil,
                        interceptor :              RequestInterceptor ? = nil,
                        serverTrustManager :       ServerTrustManager ? = nil,
                        redirectHandler :          RedirectHandler ? = nil,
                        cachedResponseHandler :    CachedResponseHandler ? = nil,
                        eventMonitors : [EventMonitor] = []) {
    let delegateQueue = OperationQueue(maxConcurrentOperationCount: 1, underlyingQueue: rootQueue, name: "org.alamofire.session.sessionDelegateQueue")
    let session = URLSession(configuration: configuration, delegate: delegate, delegateQueue: delegateQueue)

    self.init(session: session,
              delegate: delegate,
              rootQueue: rootQueue,
              startRequestsImmediately: startRequestsImmediately,
              requestQueue: requestQueue,
              serializationQueue: serializationQueue,
              interceptor: interceptor,
              serverTrustManager: serverTrustManager,
              redirectHandler: redirectHandler,
              cachedResponseHandler: cachedResponseHandler,
              eventMonitors: eventMonitors)
}

    public init(session: URLSession,
                delegate: SessionDelegate,
                rootQueue: DispatchQueue,
                startRequestsImmediately: Bool = true,
                requestQueue: DispatchQueue? = nil,
                serializationQueue: DispatchQueue? = nil,
                interceptor: RequestInterceptor? = nil,
                serverTrustManager: ServerTrustManager? = nil,
                redirectHandler: RedirectHandler? = nil,
                cachedResponseHandler: CachedResponseHandler? = nil,
                eventMonitors: [EventMonitor] = []) {
        precondition(session.delegateQueue.underlyingQueue === rootQueue,
                     "Session(session:) intializer must be passed the DispatchQueue used as the delegateQueue's underlyingQueue as rootQueue.")

        self.session = session
        self.delegate = delegate
        self.rootQueue = rootQueue
        self.startRequestsImmediately = startRequestsImmediately
        self.requestQueue = requestQueue ?? DispatchQueue(label: "\(rootQueue.label).requestQueue", target: rootQueue)
        self.serializationQueue = serializationQueue ?? DispatchQueue(label: "\(rootQueue.label).serializationQueue", target: rootQueue)
        self.interceptor = interceptor
        self.serverTrustManager = serverTrustManager
        self.redirectHandler = redirectHandler
        self.cachedResponseHandler = cachedResponseHandler
        eventMonitor = CompositeEventMonitor(monitors: defaultEventMonitors + eventMonitors)
        delegate.eventMonitor = eventMonitor
        delegate.stateProvider = self
    }
  • 1、首先在初始化的过程中给rootQueue设置了默认值
rootQueue: DispatchQueue = DispatchQueue(label: "org.alamofire.session.rootQueue")

rootQueue用来处理所有内部回调和状态更新,它是串行队列。

  • 2、设置delegateQueue也就是OperationQueue
let delegateQueue = OperationQueue(maxConcurrentOperationCount: 1, underlyingQueue: rootQueue, name: "org.alamofire.session.sessionDelegateQueue")

OperationQueue在Objective-C中就是NSOperationQueue,用来调度NSOperation的。maxConcurrentOperationCount用来控制可以同时执行的任务的数目,添加至OperationQueue对象中的所有的任务都是放到_underlyingQueue队列中执行的。这里underlyingQueue设置为了rootQueue,而且它们必须一样:
Session(session:) intializer must be passed the DispatchQueue used as the delegateQueue's underlyingQueue as rootQueue.

  • 3、requestQueueserializationQueue都把target设置成了rootQueue。

关于target queue苹果的文档有所描述:

"A dispatch queue's priority is inherited from its target queue. Use the dispatch_get_global_queue function to obtain a suitable target queue of the desired priority. If you submit a block to a serial queue, and the serial queue’s target queue is a different serial queue, that block is not invoked concurrently with blocks submitted to the target queue or to any other queue with that same target queue."

首先队列可以从target queue继承优先级。

  • .main as target for UI work
  • .global as target for other work that needs to be done as soon as possible
  • nil as target for work that just needs to get done at some point (your not bothered when)

另外串行队列的任务是不会和它所属的target queue中的任务并行处理的,也不会和任何其他与它有相同target queue的队列中的任务并行处理。这里requestQueue和serializationQueue的target queue都是rootQueue,也就保证了他们的任务都是串行处理的。

再看Session的request方法:

open func request(_ convertible : URLConvertible,
                  method :        HTTPMethod = .get,
                  parameters :    Parameters ? = nil,
                  encoding :      ParameterEncoding = URLEncoding.default,
                  headers :       HTTPHeaders ? = nil,
                  interceptor :   RequestInterceptor ? = nil)->DataRequest {
    let convertible = RequestConvertible(url: convertible,
                                         method: method,
                                         parameters: parameters,
                                         encoding: encoding,
                                         headers: headers)
    return request(convertible, interceptor: interceptor)
}

这里用外部传来的参数生成了一个RequestConvertible,它继承了URLRequestConvertible协议,该协议提供了一个生成URLRequesr的方法asURLRequest。

继续往下:

open func request(_ convertible : URLRequestConvertible, interceptor : RequestInterceptor ? = nil)->DataRequest {
    let request = DataRequest(convertible: convertible,
                              underlyingQueue: rootQueue,
                              serializationQueue: serializationQueue,
                              eventMonitor: eventMonitor,
                              interceptor: interceptor,
                              delegate: self)

    perform(request)

    return request
}

创建了DataRequest,并进行处理

func perform(_ request: DataRequest) {
    requestQueue.async {
        guard !request.isCancelled else { return }
        
        self.performSetupOperations(for: request, convertible: request.convertible)
    }
}

func performSetupOperations(for request: Request, convertible: URLRequestConvertible) {
    do {
        let initialRequest = try convertible.asURLRequest()
        rootQueue.async { request.didCreateURLRequest(initialRequest) }
            
        guard !request.isCancelled else { return }
            
        if let adapter = adapter(for: request) {
            ......
        } else {
            rootQueue.async { self.didCreateURLRequest(initialRequest, for: request) }
        }
    } catch {
        rootQueue.async { request.didFailToCreateURLRequest(with: error) }
    }
}

首先是调用URLRequestConvertible的asURLRequest方法创建URLRequest

看一下RequestConvertible的源码:

struct RequestConvertible : URLRequestConvertible {
    let url: URLConvertible
    let method: HTTPMethod
    let parameters: Parameters ?
    let encoding : ParameterEncoding
    let headers: HTTPHeaders ?

    func asURLRequest() throws->URLRequest {
        let request = try URLRequest(url : url, method : method, headers : headers)
            return try encoding.encode(request, with : parameters)
    }
}

它的asURLRequest方法还通过ParameterEncoding处理了请求参数的编码,做的就是AFNetwork的AFURLRequestSerialization一样的工作。

ParameterEncoding是一个协议,有两个结构体实现了该协议URLEncodingJSONEncoding。encoding默认是URLEncoding,来看看它的encode函数:

public func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws -> URLRequest {
    var urlRequest = try urlRequest.asURLRequest()
        
    guard let parameters = parameters else { return urlRequest }
        
    if let method = urlRequest.method, destination.encodesParametersInURL(for: method) {
        guard let url = urlRequest.url else {
            throw AFError.parameterEncodingFailed(reason: .missingURL)
        }
            
        if var urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false), !parameters.isEmpty {
            let percentEncodedQuery = (urlComponents.percentEncodedQuery.map { $0 + "&" } ?? "") + query(parameters)
            urlComponents.percentEncodedQuery = percentEncodedQuery
            urlRequest.url = urlComponents.url
        }
    } else {
        if urlRequest.value(forHTTPHeaderField: "Content-Type") == nil {
            urlRequest.setValue("application/x-www-form-urlencoded; charset=utf-8", forHTTPHeaderField: "Content-Type")
        }
            
        urlRequest.httpBody = Data(query(parameters).utf8)
    }
    
    return urlRequest
}

Destination是一个枚举类,它定义了请求参数拼接的位置。有三种情况:根据请求方法决定、拼接在Url、设置在Body里面。destination的默认值是.methodDependent,也就是根据请求方法决定。

拼接到Url:

if var urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false), !parameters.isEmpty {
    let percentEncodedQuery = (urlComponents.percentEncodedQuery.map { $0 + "&" } ?? "") + query(parameters)
    urlComponents.percentEncodedQuery = percentEncodedQuery
    urlRequest.url = urlComponents.url
}

urlComponents.percentEncodedQuery是可选类型,Swift的Optional提供了mapflatmap方法,可以不用解包就可以执行相应的操作。map和flatmap的区别在于map的闭包不能返回nil。

拼接参数:

private func query(_ parameters: [String: Any]) -> String {
    var components: [(String, String)] = []
        
    for key in parameters.keys.sorted(by: <) {
        let value = parameters[key]!
        components += queryComponents(fromKey: key, value: value)
    }
    return components.map { "\($0)=\($1)" }.joined(separator: "&")
}

创建完URLRequest之后,保存到DataRequest中:

func didCreateURLRequest(_ request : URLRequest) {
    protectedMutableState.write { $0.requests.append(request) }

    eventMonitor ? .request(self, didCreateURLRequest: request)
}

MutableState是在Request里面的定义的一个结构体,它保存了Request当前的状态、URLRequest和URLSessionTask等数据。protectedMutableState就是MutableState,只是用Protector包了一层来保证线程安全。Protector的源码:

final class Protector {
    private let lock = UnfairLock()
    ......
    @discardableResult
    func write(_ closure: (inout T) -> U) -> U {
        return lock.around { closure(&self.value) }
    }

Protector定义了一个锁,UnfairLock

final class UnfairLock {
    private let unfairLock: os_unfair_lock_t
    ......
    func around(_ closure: () -> Void) {
        lock(); defer { unlock() }
        return closure()
    }

around方法就是在执行这个闭包时先加锁,执行完成后解锁,defer内的代码在最后执行,也就是在return之前的时机。

Protector的write方法就是加锁之后,把自己的value通过引用传递给闭包对它的值进行修改。

现在adapter为空,先忽略,直接来到

rootQueue.async { self.didCreateURLRequest(initialRequest, for: request) }

func didCreateURLRequest(_ urlRequest: URLRequest, for request: Request) {
    guard !request.isCancelled else { return }
        
    let task = request.task(for: urlRequest, using: session)
    requestTaskMap[request] = task
    request.didCreateTask(task)
        
    updateStatesForTask(task, request: request)
}

调用request的task方法创建URLSessionTask,保存到requestTaskMap中,之后更新URLSessionTask的状态:

func updateStatesForTask(_ task : URLSessionTask, request : Request) {
    request.withState { (state)in
        switch (startRequestsImmediately, state) {
        case (true, .initialized):
            rootQueue.async { request.resume() }
        case (false, .initialized):
            // Do nothing.
            break
        case (_, .resumed):
            task.resume()
            rootQueue.async { request.didResumeTask(task) }
        case (_, .suspended):
            task.suspend()
            rootQueue.async { request.didSuspendTask(task) }
        case (_, .cancelled):
            task.cancel()
            rootQueue.async { request.didCancelTask(task) }
        case (_, .finished):
            // Do nothing
            break
        }
    }
}

获取request的state,同样是保证线程安全的:

func withState(perform : (State)->Void) {
    protectedMutableState.withState(perform: perform)
}

当state为.initialized并且startRequestsImmediately时,调用request.resume(),这时请求就开始了。

再回到Session初始化时

let session = URLSession(configuration: configuration, delegate: delegate, delegateQueue: delegateQueue)

这里设置的delegate就是SessionDelegate

SessionDelegate在扩展里实现了这些协议:URLSessionDelegate、URLSessionTaskDelegate、URLSessionDataDelegate、URLSessionDownloadDelegate。

看一下URLSessionDataDelegate的didReceive data方法:

open func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
    eventMonitor?.urlSession(session, dataTask: dataTask, didReceive: data)
        
    guard let request = stateProvider?.request(for: dataTask) as? DataRequest else {
        fatalError("dataTask received data for incorrect Request subclass: \(String(describing: stateProvider?.request(for: dataTask)))")
    }
    
    request.didReceive(data: data)
}

stateProvider是SessionDelegate的一个属性weak var stateProvider: SessionStateProvider?,SessionStateProvider是一个协议。Session在初始化时设置了delegate的stateProvider:

delegate.stateProvider = self

Session本身实现了这个协议:


extension Session: SessionStateProvider {
    func request(for task: URLSessionTask) -> Request? {
        return requestTaskMap[task]
    }

    func didGatherMetricsForTask(_ task: URLSessionTask) {
        requestTaskMap.disassociateIfNecessaryAfterGatheringMetricsForTask(task)
    }

    func didCompleteTask(_ task: URLSessionTask) {
        requestTaskMap.disassociateIfNecessaryAfterCompletingTask(task)
    }

    func credential(for task: URLSessionTask, in protectionSpace: URLProtectionSpace) -> URLCredential? {
        return requestTaskMap[task]?.credential ??
            session.configuration.urlCredentialStorage?.defaultCredential(for: protectionSpace)
    }

    func cancelRequestsForSessionInvalidation(with error: Error?) {
        requestTaskMap.requests.forEach { $0.finish(error: AFError.sessionInvalidated(error: error)) }
    }
}

所以最后就是在URLSession的回调中根据URLSessionDataTask来拿到DataRequest并做相应的处理。

request的didReceive方法

func didReceive(data: Data) {
    if self.data == nil {
        protectedData.directValue = data
    } else {
        protectedData.append(data)
    }
    
    updateDownloadProgress()
}

这里的Data也用Protector给包起来了,保证线程安全。

数据接收完成后,来到NSURLSessionTaskDelegate最重要的一个方法didCompleteWithError:

open func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
    eventMonitor?.urlSession(session, task: task, didCompleteWithError: error)
        
    stateProvider?.request(for: task)?.didCompleteTask(task, with: error)
        
    stateProvider?.didCompleteTask(task)
}

func didCompleteTask(_ task : URLSessionTask, with error : Error ? ) {
    self.error = self.error ? ? error
    protectedValidators.directValue.forEach { $0() }

    eventMonitor ? .request(self, didCompleteTask: task, with: error)

    retryOrFinish(error: self.error)
}

func retryOrFinish(error: Error?) {
    guard let error = error, let delegate = delegate else {
        finish(); return
    }
    
    delegate.retryResult(for: self, dueTo: error) { retryResult in
        switch retryResult {
        case .doNotRetry, .doNotRetryWithError:
            self.finish(error: retryResult.error)
        case .retry, .retryWithDelay:
            delegate.retryRequest(self, withDelay: retryResult.delay)
        }
    }
}

如果error为空或者delegate为空就会直接跳到finish方法。

func finish(error: Error? = nil) {
    if let error = error { self.error = error }
        
    // Start response handlers
    processNextResponseSerializer()
    
    eventMonitor?.requestDidFinish(self)
}

这里就会对返回结果进行解析:

func processNextResponseSerializer() {
    guard let responseSerializer = nextResponseSerializer() else {
        ......
        
        return
    }
        
    serializationQueue.async { responseSerializer() }
}

通过nextResponseSerializer来获取responseSerializer,最后执行这个解析操作。responseSerializer是保存在 mutableState.responseSerializers中的。那它是什么时候保存进去的呢?

我们再调一个方法:

AF.request("https://httpbin.org/get")
    .responseJSON { response in
        if case let .success(value) = response.result {
            print(value)
        }
}

responseJSON是DataRequest的方法:

@discardableResult
public func responseJSON(queue: DispatchQueue = .main,
                         options: JSONSerialization.ReadingOptions = .allowFragments,
                         completionHandler: @escaping (DataResponse) -> Void) -> Self {
    return response(queue: queue,
                    responseSerializer: JSONResponseSerializer(options: options),
                    completionHandler: completionHandler)
}
@discardableResult
public func response(
    queue: DispatchQueue = .main,
    responseSerializer: Serializer,
    completionHandler: @escaping (DataResponse) -> Void)
    -> Self
{
    appendResponseSerializer {
        // 数据解析的操作
        ......
    }
        
    return self
}

调用了appendResponseSerializer方法,传入一个闭包,这个闭包就是解析请求结果的函数。

func appendResponseSerializer(_ closure: @escaping () -> Void) {
    protectedMutableState.write { mutableState in
        mutableState.responseSerializers.append(closure)
            
        if mutableState.state == .finished {
            mutableState.error = AFError.responseSerializationFailed(reason: .responseSerializerAddedAfterRequestFinished)
        }
            
        if mutableState.responseSerializerProcessingFinished {
            underlyingQueue.async { self.processNextResponseSerializer() }
        }
    }
}

把这段代码改一下形式:

let tmpClosure : (inout MutableState) -> Void = { mutableState in
    mutableState.responseSerializers.append(closure)
    
    if mutableState.state == .finished {
        mutableState.error = AFError.responseSerializationFailed(reason: .responseSerializerAddedAfterRequestFinished)
    }
            
    if mutableState.responseSerializerProcessingFinished {
        self.underlyingQueue.async { self.processNextResponseSerializer() }
    }
}

protectedMutableState.write(tmpClosure)
// lock.around { tmpClosure(&self.value) }

就是加锁之后执行了tmpClosure,最终的结果就是以下代码执行:

mutableState.responseSerializers.append(closure)

if mutableState.state == .finished {
    mutableState.error = AFError.responseSerializationFailed(reason: .responseSerializerAddedAfterRequestFinished)
}

if mutableState.responseSerializerProcessingFinished {
    self.underlyingQueue.async { self.processNextResponseSerializer() }
}

也就是request的mutableState增加一个responseSerializer,把它保存在mutableState.responseSerializers

这里有两个关键的状态判断mutableState.state == .finishedmutableState.responseSerializerProcessingFinished

如果当前request的状态是finished,那就会设置一个responseSerializerAddedAfterRequestFinished错误。什么时候request的状态会变为finished呢?在processNextResponseSerializer函数中,对调用nextResponseSerializer方法去取responseSerializer,如果取不到就会进入以下方法:

var completions: [() -> Void] = []
            
protectedMutableState.write { mutableState in
    completions = mutableState.responseSerializerCompletions
                
    // Clear out all response serializers and response serializer completions in mutable state since the
    // request is complete. It's important to do this prior to calling the completion closures in case
    // the completions call back into the request triggering a re-processing of the response serializers.
    // An example of how this can happen is by calling cancel inside a response completion closure.
    mutableState.responseSerializers.removeAll()
    mutableState.responseSerializerCompletions.removeAll()
                
    if mutableState.state.canTransitionTo(.finished) {
        mutableState.state = .finished
    }
                
    mutableState.responseSerializerProcessingFinished = true
}
            
completions.forEach { $0() }
            
// Cleanup the request
cleanup()

这个时候就会设置request的state为.finished,同时responseSerializerProcessingFinished也会设置为true。

创建完URLRequest后可以做一些自定义的处理,也就是前面略过的adapter和Interceptor的作用。

func performSetupOperations(for request: Request, convertible: URLRequestConvertible) {
    do {
        let initialRequest = try convertible.asURLRequest()
        rootQueue.async { request.didCreateURLRequest(initialRequest) }
            
        guard !request.isCancelled else { return }
            
        if let adapter = adapter(for: request) {
            adapter.adapt(initialRequest, for: self) { result in
                do {
                    let adaptedRequest = try result.get()
                    
                    self.rootQueue.async {
                        request.didAdaptInitialRequest(initialRequest, to: adaptedRequest)
                        self.didCreateURLRequest(adaptedRequest, for: request)
                    }
                } catch {
                    let adaptError = AFError.requestAdaptationFailed(error: error)
                    self.rootQueue.async { request.didFailToAdaptURLRequest(initialRequest, withError: adaptError) }
                }
            }
        } else {
            rootQueue.async { self.didCreateURLRequest(initialRequest, for: request) }
            }
    } catch {
        rootQueue.async { request.didFailToCreateURLRequest(with: error) }
    }
}

调用adapter(for: request)来获取RequestAdapter。RequestAdapter是个协议,定义了一下方法:

func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (AFResult) -> Void)

看看adapter(for request: Request)做了什么:

func adapter(for request: Request) -> RequestAdapter? {
    if let requestInterceptor = request.interceptor, let sessionInterceptor = interceptor {
        return Interceptor(adapters: [requestInterceptor, sessionInterceptor])
    } else {
        return request.interceptor ?? interceptor
    }
}

Interceptor -> RequestInterceptor -> RequestAdapter, RequestRetrier

如果request的interceptor和session的interceptor都不为空,则返回Interceptor,否则单独返回它们不为空的那个。

session的interceptor默认也是nil。

RequestInterceptor的adapt方法默认是什么都不做的:

public func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (AFResult) -> Void) {
    completion(.success(urlRequest))
}

这里@escaping用来定义逃逸闭包。因为这个闭包可能在函数执行完后才执行,比如以下情况:

public func escapingClosure (completion: @escaping () -> Void) {
    DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 5000) {
        completion()
    }
}

如果我们把@escaping去掉会出现以下错误:
Closure use of non-escaping parameter 'completion' may allow it to escape

Interceptor是把requestInterceptor和sessionInterceptor保存起来,然后用递归调用RequestAdapter的adapter方法:

private func adapt(
    _ urlRequest: URLRequest,
    for session: Session,
    using adapters: [RequestAdapter],
    completion: @escaping (AFResult) -> Void)
{
    var pendingAdapters = adapters
        
    guard !pendingAdapters.isEmpty else { completion(.success(urlRequest)); return }
        
    let adapter = pendingAdapters.removeFirst()
        
    adapter.adapt(urlRequest, for: session) { result in
        switch result {
        case .success(let urlRequest):
            self.adapt(urlRequest, for: session, using: pendingAdapters, completion: completion)
        case .failure:
            completion(result)
        }
    }
}

如果有一个出错则直接退出。

  • NSOperation 高级用法之NSOperation基础(NSOperation源码分析)(上)
  • target parameter in DispatchQueue
  • Swift4 中访问控制 private和fileprivate的区别

你可能感兴趣的:(Alamofire源码学习)