Alamofire源码分析(4)——task

上次分析完了DataRequest层,接下来承接之前说的继续分析:

SessionManager.default  //直接跳过Alamofire层调用也可以
.request(url, method: .get, parameters: parameters)
.response { (result) in
    print(result)
}
open class SessionManager {
    ...
    @discardableResult
    open func request(
        _ url: URLConvertible,
        method: HTTPMethod = .get,  /*默认为get方法*/
        parameters: Parameters? = nil,
        encoding: ParameterEncoding = URLEncoding.default,
        headers: HTTPHeaders? = nil)
        -> DataRequest
    {
        var originalRequest: URLRequest?
        //创建URLRequest
        do {
            originalRequest = try URLRequest(url: url, method: method, headers: headers)
            let encodedURLRequest = try encoding.encode(originalRequest!, with: parameters)
            return request(encodedURLRequest)//轮到分析这里
        } catch {
            return request(originalRequest, failedWith: error)
        }
    }
    ...
}
  1. 之前分析到这一步:request(encodedURLRequest),现在就来看看它:
open class SessionManager {
    ...
    @discardableResult
    open func request(_ urlRequest: URLRequestConvertible) -> DataRequest {
        var originalRequest: URLRequest?

        do {
            originalRequest = try urlRequest.asURLRequest()
            let originalTask = DataRequest.Requestable(urlRequest: originalRequest!)

            let task = try originalTask.task(session: session, adapter: adapter, queue: queue)
            let request = DataRequest(session: session, requestTask: .data(originalTask, task))//工厂设计模式
            //一一对应建立绑定关系而非依赖关系,绑定后获取方便
            delegate[task] = request//重写了下标引用,降低耦合度

            if startRequestsImmediately {
                request.resume()
            }

            return request
        } catch {
            return request(originalRequest, failedWith: error)
        }
    }
    ...
}
  1. 首先创建了一个结构体RequestableRequestable继承了TaskConvertible协议),这个结构体变量名虽为originalTask,但并不是URLSessionTask,而是由它创建URLSessionTask
open class DataRequest: Request {
    
    struct Requestable: TaskConvertible {
        let urlRequest: URLRequest//结构体属性默认为初始化参数

        func task(session: URLSession, adapter: RequestAdapter?, queue: DispatchQueue) throws -> URLSessionTask {
            do {
                let urlRequest = try self.urlRequest.adapt(using: adapter)
                return queue.sync { session.dataTask(with: urlRequest) }
            } catch {
                throw AdaptError(error: error)
            }
        }
    }
    ...
}
protocol TaskConvertible {
    func task(session: URLSession, adapter: RequestAdapter?, queue: DispatchQueue) throws -> URLSessionTask
}
  1. 然后用RequestableURLSessionTask创建DataRequestDataRequest继承了Request),Request初始化时,通过枚举任务类型创建对应任务代理进行下发任务:
open class DataRequest: Request {
  ...
}
open class Request {
    ...
    init(session: URLSession, requestTask: RequestTask, error: Error? = nil) {
        self.session = session
        //分发任务
        switch requestTask {
        case .data(let originalTask, let task):
            taskDelegate = DataTaskDelegate(task: task)
            self.originalTask = originalTask
        case .download(let originalTask, let task):
            taskDelegate = DownloadTaskDelegate(task: task)
            self.originalTask = originalTask
        case .upload(let originalTask, let task):
            taskDelegate = UploadTaskDelegate(task: task)
            self.originalTask = originalTask
        case .stream(let originalTask, let task):
            taskDelegate = TaskDelegate(task: task)
            self.originalTask = originalTask
        }

        delegate.error = error
        delegate.queue.addOperation { self.endTime = CFAbsoluteTimeGetCurrent() }//记录时间
    }
    ...
}
  1. 创建完DataRequest后,调用delegate[task] = requestdelegate便是SessionManager初始化时默认创建的SessionDelegate),目的是为了使用时获取方便(通过重写下标引用进行绑定,可以降低耦合度)
open class SessionDelegate: NSObject {
    ...
    open subscript(task: URLSessionTask) -> Request? {
        get {
            lock.lock() ; defer { lock.unlock() }
            return requests[task.taskIdentifier]
        }
        set {
            lock.lock() ; defer { lock.unlock() }
            requests[task.taskIdentifier] = newValue
        }
    }
    ...
}
  1. 下一步该是调用request.resume()启动任务了,最终便会调用task.resume(),并发起通知:
open class Request {
    ...
    open func resume() {
        ...
        task.resume()
        //通知启动
        NotificationCenter.default.post(
            name: Notification.Name.Task.DidResume,
            object: self,
            userInfo: [Notification.Key.Task: task]
        )
    }
    ...
}

task启动后,先分析到这里。下一篇详细看看执行任务的TaskDelegate。

你可能感兴趣的:(Alamofire源码分析(4)——task)