最近我读了 Alamofire 的源代码,我真的很困惑 Alamofire 如何确保以正确的顺序调用响应方法。我希望有人(也许 matt 大声笑)可以帮助我。
示例,这样一个简单的GET请求
Alamofire.request(.GET, "https://api.github.com/users/octocat/received_events")
在分析了它的工作流程后,我发布了我的理解
创建 请求和基础 NSURLSession 。
public func request(method: Method, URLString: URLStringConvertible, parameters: [String: AnyObject]? = nil, encoding: ParameterEncoding = .URL) -> Request {
return Manager.sharedInstance.request(method, URLString, parameters: parameters, encoding: encoding)
}
此方法将创建请求:请求对象,该对象将包含基础 NSURLSessionDataTask 对象。 Manager.sharedInstance 已经设置了 NSURLSession 并将自己设置为该会话的委托。 Manager.sharedInstance 对象会将自定义对象 request.delegate 保存在自己的属性委托
创建这些对象后, Alamofire 会立即发送此请求。
public func request(URLRequest: URLRequestConvertible) -> Request {
var dataTask: NSURLSessionDataTask?
dispatch_sync(queue) {
dataTask = self.session.dataTaskWithRequest(URLRequest.URLRequest)
}
let request = Request(session: session, task: dataTask!)
delegate[request.delegate.task] = request.delegate
if startRequestsImmediately {
request.resume()
}
return request
}
由于 Manager.sharedInstance 将自己设置为基础 NSURLSession 的委托,因此在收到数据时,将调用委托方法
public func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveData data: NSData) {
if dataTaskDidReceiveData != nil {
dataTaskDidReceiveData!(session, dataTask, data)
} else if let delegate = self[dataTask] as? Request.DataTaskDelegate {
delegate.URLSession(session, dataTask: dataTask, didReceiveData: data)
}
}
如果用户想要获得响应并执行相关操作,他将使用以下公共API
// Here the request is a Request object
self.request?.responseString { (request, response, body, error) in
// Something do with the response
}
让我们看看 responseString(_:completionHandler:)方法做了什么
public func response(queue: dispatch_queue_t? = nil, serializer: Serializer, completionHandler: (NSURLRequest, NSHTTPURLResponse?, AnyObject?, NSError?) -> Void) -> Self {
delegate.queue.addOperationWithBlock {
let (responseObject: AnyObject?, serializationError: NSError?) = serializer(self.request, self.response, self.delegate.data)
dispatch_async(queue ?? dispatch_get_main_queue()) {
completionHandler(self.request, self.response, responseObject, self.delegate.error ?? serializationError)
}
}
return self
}
我的问题是如何在 3 之后保证 5 ,所以用户可以获得不属于它的所有响应,因为 self.response 此时将完全加载。
是否因为NSURLSession的后台处理发生在同一个队列上 - delegate.queue ,这是在 Alamofire 中创建的:
//class Request.TaskDelegate: NSObject, NSURLSessionTaskDelegate
self.queue = {
let operationQueue = NSOperationQueue()
operationQueue.maxConcurrentOperationCount = 1
operationQueue.suspended = true
if operationQueue.respondsToSelector("qualityOfService") {
operationQueue.qualityOfService = NSQualityOfService.Utility
}
return operationQueue
}()
我的理解是否正确,这是怎么发生的?如果你能指出我可以参考的地方,可能需要对 RunLoop 和 NSURLSession的线程机制有所了解,谢谢你。