Core文件夹:
Alamofire.swift - - - 该文件中主要是给用户提供一些便利的调用方法,用户可以直接调用该文件中的便利方法来使用Alamofire相关功能。
Manager.swift - - - Manager中定义了Session对象,Session相关的Delegate,以及Delegate执行的队列等相关信息,在Manager中创建Request对象发起请求。Manager管理的就是各种请求,Manager对象是以单例的形式对外开放的。
Request.swift - - - 该文件如其名,就是负责创建Session的各种task的,并执行相关的SessionTask,并调用相关书籍解析的功能模块对数据进行解析并通过回调返回给用户。
ParameterEncoding.swift - - - 负责请求参数的各种编码(URL、URLEncodeInURL、JSON、PropertyList等编码),并将编码之后的数据与URLRequest结合后的结果进行返回。
Result.swift - - - 对解析后的数据封装成Result对象;
Response.swift - - - 负责将服务器相应的数据进行封装生成Response对象,该对象中就包括上述的Result对象,用户最终工会通过闭包回调的形式获取到该Response的对象。
Notifications.swift - - - 其实是一个Notification结构体,该结构体中定义了一些字符串,这些字符串就是所需通知的key,当网络请求DidResume、DIdSuspend、DIdCancel、DidComplete都会发出通知。
Error.swift - - - 其实是一个Error的结构体,其中封装的是各种错误状态。
Features文件夹:
Download.swift - - - 对Manager和Request类进行扩展,使其支持Download Task,其中封装了NSURLSessionDownloadDelegate相关代理方法。
Upload.swift - - - 在该文件中格式对Manager和Request类进行的扩展,使其支持Upload Task,其中封装了NSURLSessionDataDelegate中获取上传数据进度的代理方法,也就是taskDidSendBodyData代理方法。
MultipartFormData.swift - - - 该文件从名字就可以看出是为了组织多表单数据上传的数据的,在Upload task中就使用到了MultipartFormData。
Stream.swift - - - 和Download和Upload文件相似,该文件中也是对Manager和Request做延展,主要使其支持数据流的传输,其中主要封装和实现了NSURLSessionStreamDelegate相关的代理方法。
ResponseSerialization.swift - - - 该文件中主要是对Request类进行数据解析的延展的。其中封装了各种对响应数据的解析方式,其中包括Data、String、JSON、PropertyList等解析方式。
NetworkReachabilityManager.swift - - - 该文件主要是对SystemConfiguration.framework中的SCNetworkReachability相关的东西进行封装,主要用来管理和监听网络状态的变化。
ServerTrustPolicy.swift - - - 这个文件主要是对NSURLSession做的延展,其中定义了各种网络请求的认证策略,主要证书认证相关东西。
Tileline.swift - - - 该文件主要为了方便调试而生,其中记录了相关操作的时间点,并且对其进行记录,便于在Debug时使用到。
Validation.swift - - - 主要是用来验证请求是否成功,如果出错了就做相应的处理。
2、我的理解:Alamofire在实现中的特点;
(1)、根据URL生成task是使用dispatch_sync进行(防止多线程问题,task的生成在一个线程内);
dispatch_sync(queue) {
dataTask = self.session.dataTaskWithRequest(URLRequest.URLRequest)
}
(2)、TaskDelegate的定义在Request类中,以类中类的方式存在,且只继承于NSObject;
(3)、SessionDelegate扩展了下标方法,下标方法中,取使用同步的dispatch取,存则使用dispatch_barrier_async去存,barrier的task会在这个concurrent的queue中的所有在自己之前开始执行的任务执行完成后再开始,同样在自己之后提交到这个concurrent的queue中的任务也会在自己执行完成之后开始执行;这样做很好的避免了资源竞争引起的数据不同步;
同时,SessionDelegate中设置了 subdelegates 的 [Int : Request.TaskDelegate] 键值对来分发delegate的回调处理;下标方法操作的就是 subdelegate ,而且在get方法中,根据参数的task的taskIdentifier来取得对应的delegate,且获取的步骤使用了sync的同步操作;??????????,不太明白为什么;而在set方法中,是使用了barrier 的方法来赋值新值;使用的依然是全局的subdelegateQueue,set里面之所以使用 barrier 可能是因为这个队列是全局使用的,为了防止我再存入新的值的时候会有调用;但是一个task对应一个taskIdentifier应该也不会重复的吧;???????
(4)、具体请求的响应;
DataTaskDelegate、DownloadTaskDelegate、UploadTaskDelegate都是继承于TaskDelegate,而在TaskDelegate中有一个 NSOperationQueue 类型的属性 queue ,因为继承关系,这三个delegate中也是有这个变量的;同样在TaskDelegate的初始化中,也初始化了这个queue;且初始的suspended为true,maxConcurrentOperationCount为1;初始化部分使用了匿名方法的方式进行;对应的,在deist方法中调用了queue的cancelAllOperations方法和suspended设为了false;且当接收到数据后才会被置为false,此时它内部添加的operation即response的解析化才回真正执行,解析后执行回调completionHandler
也就是说其实请求成功执行的回调其实封装在了一个在=operation上,而一个delegate有一个queue,一个queue中只有一个operation,而queue在创建的时候开始都是暂停的,直到收到数据,这一个请求的代理方法回去开启自己对应的queue,而因为queue已经开启,之前添加的operation开始执行;
这里也有另外一点,DataTaskDelegate、DownloadTaskDelegate、UploadTaskDelegate三个delegate,虽然是名字中有delegate,但并不是单纯的protocol,而是声明为了class ,但是其中实现了NSURLSessionDataDelegate、NSURLSessionDownloadDelegate协议方法;其中UploadTaskDelegate继承于DataTaskDelegate
(5)、一个请求发生的方法调用;
调用request(...)公共方法1 -> 1中调用了 Manager.shareInstance.request(…) 2 -> 2中调用了该单例中的另一 request(…) 方法3 -> 3中调用了 Request(…) 方法4,创建一个Request对象 -> 4中调用了 DataTaskDelegate(…) 方法5来初始化一个TaskDelegate的子类,而在创建这个子类时,也就有了类型为NSOperationQueue的变量queue(初始为暂停),同时也添加了一个operation -> 因为5其实是带有代理回调的,所以请求结束后,会触发系统session的毁掉方法,再进行传递;
这样的处理方式,其实是一个请求一个Request对象,Request对象中包含一个delegate对象,也就对应了一个queue,因为queue只维护一个operation,而一个请求的发起和回调都是在一个operation上面进行,从而保证数据请求不会错乱,不会是A请求的结果却回调了B请求的回调的执行;还因为A和B都不是一个线程;
参考:
http://www.cocoachina.com/ios/20151117/14240.html 这一篇文章讲的很好,刚开始我自己看源码确实理不清这些关系,对着这个一个类一个类的看下去,才终于明白了整个的调用层次;
http://www.cnblogs.com/ludashi/p/5588044.html 这篇文章会告诉你每个类都做了什么
- iOS开发之Alamofire源码深度解析
今天博客中的Alamofire源码的版本是以现在最新的3.4版本为例.上篇博客系统的对NSURLSession相关的东西进行了详细的解析,详情请看<详解NSURLSession>,为了就是 ...
- Alamofire源码解读系列(十一)之多表单(MultipartFormData)
本篇讲解跟上传数据相关的多表单 前言 我相信应该有不少的开发者不明白多表单是怎么一回事,然而事实上,多表单确实很简单.试想一下,如果有多个不同类型的文件(png/txt/mp3/pdf等等)需要上传给 ...
- Alamofire源码解读系列(十二)之请求(Request)
本篇是Alamofire中的请求抽象层的讲解 前言 在Alamofire中,围绕着Request,设计了很多额外的特性,这也恰恰表明,Request是所有请求的基础部分和发起点.这无疑给我们一个Req ...
- iOS开发之Alamofire源码解析
今天博客中的Alamofire源码的版本是以3.4版本为例.上篇博客系统的对NSURLSession相关的东西进行了详细的解析,详情请看<详解NSURLSession>,为了就是给本篇博客 ...
- iOS开发之Alamofire源码解析前奏--NSURLSession全家桶
今天博客的主题不是Alamofire, 而是iOS网络编程中经常使用的NSURLSession.如果你想看权威的NSURLSession的东西,那么就得去苹果官方的开发中心去看了,虽然是英文的,但是结 ...
- Java集合专题总结(1):HashMap 和 HashTable 源码学习和面试总结
2017年的秋招彻底结束了,感觉Java上面的最常见的集合相关的问题就是hash--系列和一些常用并发集合和队列,堆等结合算法一起考察,不完全统计,本人经历:先后百度.唯品会.58同城.新浪微博.趣分 ...
- jQuery源码学习感想
还记得去年(2015)九月份的时候,作为一个大四的学生去参加美团霸面,结果被美团技术总监教育了一番,那次问了我很多jQuery源码的知识点,以前虽然喜欢研究框架,但水平还不足够来研究jQuery源码, ...
- MVC系列——MVC源码学习:打造自己的MVC框架(四:了解神奇的视图引擎)
前言:通过之前的三篇介绍,我们基本上完成了从请求发出到路由匹配.再到控制器的激活,再到Action的执行这些个过程.今天还是趁热打铁,将我们的View也来完善下,也让整个系列相对完整,博主不希望烂尾. ...
- MVC系列——MVC源码学习:打造自己的MVC框架(三:自定义路由规则)
前言:上篇介绍了下自己的MVC框架前两个版本,经过两天的整理,版本三基本已经完成,今天还是发出来供大家参考和学习.虽然微软的Routing功能已经非常强大,完全没有必要再“重复造轮子”了,但博主还是觉 ...
随机推荐
- 显示天气预报的Demo
实现的效果如下所示: 代码如下: ViewController.h #import <UIKit/UIKit.h> @interface ViewController : UIViewCo ...
- Tomcat中间件URL中文字符传递问题
1. 问题描述: tomcat中如果URL中需要传递中文参数,需要配置tomcat的service.xml中文传递的编码方式,否则中文传递将出现乱码,导致程序异常. 2. 解决方式: 修改tomcat ...
- python "yield"(转载)
转载地址:http://www.ibm.com/developerworks/cn/opensource/os-cn-python-yield/ 您可能听说过,带有 yield 的函数在 Python ...
- A*搜索
1,从点A开始,并且把它作为待处理点存入一个"开启列表".开启列表就像一张购物清单.尽管现在列表里只有一个元素,但以后就会多起来.你的路径可能会通过它包含的方格,也可能不会.基本上 ...
- Velocity语言的介绍
Velocity语言的介绍 2016-09-06 15:39:25 语言介绍 Velocity是一种Java模版引擎技术,是一个基于Java的模板引擎(template engine).她允许任何人简 ...
- (转)jquery easyui treegrid使用小结 (主要讲的是如何编辑easyui中的行信息包括添加 下拉列表等)
在实际应用中可能会碰到不同的需求,比如会根据每行不同的参数或属性设置来设置同列不同的editor类型,这时原有的例子就显的有点太过简单,不能实现我们的需求,现在应用我在项目中的操作为例,显示下实现同列 ...
- ABAP 字符串操作
1).SHIFT:截断字符串 SHIFT {c} [BY {n} PLACES] [{mode}].: 作用:去掉字符串的前n个位置的字符,如果n未指定,默认为1,如果指定的n小于等于0,则字符串不变 ...
- 什么是publickeytoken及publickeytoken的作用
什么是publickeytoken及publickeytoken的作用 dll的publickeytoken的作用.
- Java多线程开发技巧
很多开发者谈到Java多线程开发,仅仅停留在new Thread(...).start()或直接使用Executor框架这个层面,对于线程的管理和控制却不够深入,通过读<Java并发编程实践&g ...
- tomcat 解决端口8080冲突
这样的问题有时会因为eclipse等IDE使用bug导致. 解决方法: 使用dos 命令 运行---cmd--netstat -ano|findstr 8080 键入命令后,dos下会显示正在使用80 ...