美文网首页
Alamofire源码分析(4)——task

Alamofire源码分析(4)——task

作者: 无悔zero | 来源:发表于2020-12-10 00:37 被阅读0次

    上次分析完了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

          本文链接:https://www.haomeiwen.com/subject/rhucgktx.html