Alamofire 关于Response的思考

匿名 (未验证) 提交于 2019-12-02 23:55:01

Alamofire 关于Response的思考。

你好,我是Emma,今天我们开启对Alamofire 关于Response的思考。主要的思考方向以下方示例为切入点。

示例:

SessionManager.default.request(urlString)     //默认的请求     .response(completionHandler: { (dataResponse) in         dataResponse.response     })     //自定义序列化的请求     .response(responseSerializer: DataResponseSerializer<String>.init(serializeResponse: { (request, response, data, error) -> Result<String> in         print("原始数据:\(response)")         return .success("成功啦")     })) { (dataResponse) in          print(dataResponse)     }     //系统封装过的序列化请求     .responseJSON { (jsonResponse) in         print(jsonResponse) } 

###1.Alamofiren中Response这个角色的作用是什么?
首先在查看源码之前,通过上面的代码我们思考一下,我们认为的Response是用来做什么的?这时候我们很有可能由于使用Alamofire的惯性会认为这个Response的作用是解析result中返回的数据的。这个观点我们用代码验证并订正。
进入Response方法:

1.Response返回的是一个闭包,闭包的参数是DefaultDataResponse,这个包相当于是`{ (lgDataResponse) in         lgDataResponse     }`这个包的处理。 2.添加异步请求队列 `delegate.queue.addOperation {}` 3.返回主线程 `(queue ?? DispatchQueue.main).async {}` 4.创建对象 `var dataResponse` 5.该对象的来源:源方法的声明,方法中的属性,属性的调用,属性的初始化等函数方法的具体下层操作。 
//DefaultDataResponse是一个总的结构体,里面保存了很多属性,那么思考这些属性的数据是从什么地方来的呢? DefaultDataResponse(                 request: self.request,                 response: self.response,                 data: self.delegate.data,                 error: self.delegate.error,                 timeline: self.timeline             ) 
总结从上面可以看出Response作用典型的是存储,更像model一些。 

###2.Alamofiren中Response保存了什么?

@discardableResult public func response(queue: DispatchQueue? = nil, completionHandler: @escaping (DefaultDataResponse) -> Void) -> Self {     delegate.queue.addOperation {         (queue ?? DispatchQueue.main).async {             var dataResponse = DefaultDataResponse(                 request: self.request,                 response: self.response,                 data: self.delegate.data,                 error: self.delegate.error,                 timeline: self.timeline             )              dataResponse.add(self.delegate.metrics)              completionHandler(dataResponse)         }     }      return self } 

####1.Request的来源:
response中的request是通过传过来的是什么类型来保存好响应的request。

/// The request sent or to be sent to the server. open override var request: URLRequest? {     if let request = super.request { return request }     if let requestable = originalTask as? Requestable { return requestable.urlRequest }      return nil } 

####2.response: self.response的来源:

类似于参数 = 值

左边的Response是public let response: HTTPURLResponse?意在表示对于URL服务器给出的返回,只是结构体保存的一种存储方式。

右边的self.response是服务器返回的真正的任何请求
open var response: HTTPURLResponse? { return task?.response as? HTTPURLResponse }
通俗的将调用的时候:

//lgDataResponse相当于DefaultDataResponse, //response相当于左边的参数。 //而连起来用lgDataResponse.response这个的值就相当于右边的self.response,即服务器返回的任意的响应。 .response(completionHandler: { (lgDataResponse) in     lgDataResponse.response }) 

####3.data: self.delegate.data的来源?这里的self.delegate指的是哪个代理?或者说这里将什么data值进行了保存?

class DataTaskDelegate: TaskDelegate, URLSessionDataDelegate {     override var data: Data? {         if dataStream != nil {             return nil         } else {             return mutableData         }     } } 

data的来源是mutableData,这里的代理是DataTaskDelegate或者是DownloadTaskDelegate代理,具体是请求的时候task是什么请求类型。
mutabledata的处理:

func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) { //初始化代码响应时间     if initialResponseTime == nil { initialResponseTime = CFAbsoluteTimeGetCurrent() } //判断响应的任务是否已经是接受到的信息了,是就直接返回?是这么理解吗?还有就是如果真的是这么理解的话,那么怎么判断出是否是已经请求过过的数据呢?     if let dataTaskDidReceiveData = dataTaskDidReceiveData {         dataTaskDidReceiveData(session, dataTask, data)     } else {         if let dataStream = dataStream {             dataStream(data)         } else {             mutableData.append(data)         }         。。。     } } 

DataTaskDelegate中的

func urlSession(){  } 

var dataTaskDidReceiveResponse: ((URLSession, URLSessionDataTask, URLResponse) -> URLSession.ResponseDisposition)? var dataTaskDidBecomeDownloadTask: ((URLSession, URLSessionDataTask, URLSessionDownloadTask) -> Void)? var dataTaskDidReceiveData: ((URLSession, URLSessionDataTask, Data) -> Void)? var dataTaskWillCacheResponse: ((URLSession, URLSessionDataTask, CachedURLResponse) -> CachedURLResponse?)? 

这些变量的声明都是有联系的这个设计思想是什么?我看dataTaskDidReceiveData在SessionDelegate中也有,并且类型时open var 的我尝试在写SessionDelegate.dataTaskDidReceiveData这个没有提示,这个是做什么用的?在DataTaskDelegate中,这些声明用来做什么的?

最关键的是:无法理解为什么mutableData.append(data)要写在这里?我目前字面上的理解是数据任务接收到数据,数据都是不完整的,然后mutableData是将数据拼完整,这个理解有问题吗?如果数据接收完了之后就调用上面这个分支

if let dataTaskDidReceiveData = dataTaskDidReceiveData { //回调出去         dataTaskDidReceiveData(session, dataTask, data)     }       

就将数据传递出去。
简单说就是对外闭包是否实现了?如果实现了就证明用户要自己处理。

if let dataTaskDidReceiveData = dataTaskDidReceiveData {     dataTaskDidReceiveData(session, dataTask, data) } else {     if let dataStream = dataStream {     //判断是否传输完毕         dataStream(data)     } else {     //传输完毕,回调出去,否则一直拼接         mutableData.append(data)     }     。。。 } 

SessionDelegate 中dataTaskDidReceiveData方法open var是对外提供的方法,这个可以提供外面调用,现在这个taskDelegate中的方法不是open var的也可以我也没有看见dataTaskDidReceiveData方法在哪里回调了啊?

我的理解里,不是completionHandler(disposition)调用这种逃逸闭包的时候才执行外面闭包实现中的方法吗?就像dataTaskDidReceiveResponse这个属性的session方法实现一样。这里面就有将completionHandler(disposition)回调,可是dataTaskDidReceiveData中就没有completionHandler(disposition)啊怎么回调出去的?
待续待续。。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!