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)啊怎么回调出去的?
待续待续。。
来源:51CTO
作者:maniao1991
链接:https://blog.csdn.net/maniao1991/article/details/100084759