XMNetworking源码阅读学习

闲话不说了,今天来学习XcodeMen team的轻量级网络库XMNetworking

前阵子看源码的时候,还是有点懵逼,自动昨天自己画了思维导图,对网络层的结构分析了一下,今天再来看,发现就豁然开朗了,感觉挺好的

XMConst 文件

一个定义全局文件变量文件,用结构体定义了上传、下载、普通三种请求方式,6种请求方法,3种请求序列化的方式,4种回应序列化的方式,三大类请求block(单个请求、批量请求、链式请求)以及一个用来对请求回应做处理的通用block,这应该都是好理解的。

XMRequest

XMRequest文件定义了XMRequest、XMBatchRequest、XMChainRequest、XMUploadFormData四个类。

XMRequest 主要是提供请求的配置信息,也就是请求方法、头部、URL、请求和回应序列化方式、超时时间等,还有另外几个 readonly 修饰的block类型属性,这几个block会在请求落地时候调用并返回业务数据。还有用语上传数据的 uploadFormDatas 属性,这个属性规定了数组里的对象必须是uploadFormDatas 对象。还提供了几个快速添加 uploadFormData的方法

XMBatchRequest、XMChainRequest 并没有使用继承的方式,而是采用了组合。这两个请求类通过持有XMRequest 对象作为属性来获得XMRequest对象的特征,同时又可以自己衍生自己的特性。

XMUploadFormData为上传请求的数据对象,并提供了多个类方法来创建新对象
整体来说,XMRequest文件提供的都是请求起飞的配置。

XMCenter

XMCenter文件定义了两个类,分别是XMCenter和XMConfig。
XMConfig类是XMCenter的配置类,而这些XMCenter配置信息,又被间接提供到了request手里。

XMCenter类是整个框架的核心类,并且是个单例类。将通过请求的流程来分析源码。
1、 - (void)setupConfig:(void(^)(XMConfig *config))block;
方法提供的config对象完成XMCenter的基本配置信息,这样XMCenter单例对象将能直接使用这些配置。
2、 - (void)setResponseProcessBlock:(XMCenterResponseProcessBlock)block;
这个方法将用来处理返回的response,注意,这个block会在返回成功之前调用,我们可以通过这个block来处理请求成功,但是业务出现错误的情况,并且创建一个NSError实例传递给block,这样在回调的block中,就直接走 FailureBlock,而不走SuccessBlock。也就是劫持response,主动改变response走向。
3、接下来就是一连串的便利请求发起方法,但这些请求发起方法的下一层,就是参数最后的那个方法,也就是这个

- (NSUInteger)sendRequest:(XMRequestConfigBlock)configBlock
           onProgress:(nullable XMProgressBlock)progressBlock
            onSuccess:(nullable XMSuccessBlock)successBlock
            onFailure:(nullable XMFailureBlock)failureBlock
           onFinished:(nullable XMFinishedBlock)finishedBlock;

其余调起请求的方法,只是在这个方法上封装了一层,并且固定了一些参数,所以叫做便利方法。这个方法的实现如下

    XMRequest *request = [XMRequest request];
    XM_SAFE_BLOCK(configBlock, request);
    [self xm_processRequest:request onProgress:progressBlock onSuccess:successBlock onFailure:failureBlock onFinished:finishedBlock];
    return [self xm_sendRequest:request];

这个方法的实现了,生成了一个XMRequest实例request,并且通过XM_SAFE_BLOCK(configBlock, request);调用configBlock(这个是request的配置block,不要别错看成XMcenter),将调起这个接口时候,配置的request信息(接口名字、请求方法、参数等),填充到这request实例上来。
4、再接下来就是通过为接口调起时配置的request做修饰,可能是新的参数、Header,URL等这些。
5、处理完了request,那就是带着request起飞了,也就是这个方法:
- (NSUInteger)xm_sendRequest:(XMRequest *)request 这个方法的实现,将调用另外 XMEngine 来实现真正的起飞。并且通过block来接收回调处理。返回值将和对应的请求task相互绑定,用于取消请求的操作。
6、回调方法有成功和失败两种。但在执行回调时候,是在一个私有线程,也就是XCenter自己的线程种callbackQueue。并且失败的回调还有机会再次让request起飞。
7、回调函数之行完成之后,就需要清理回调的block,回调的block是和request成员,所有需要调用request的 - (void)cleanCallbackBlocks方法,置空与回调相关block(successBlock ;failureBlock ; finishedBlock ;progressBlock 。
8、链式请求和批量请求,过程都差不多,只在请求发起时候稍有差别。

整个流程差不多这样了,在看看代码,应该是没问题了。并且,作者的注释本来还有使用方法也写得很清楚了。

XMEngine

XMEngine是请求的发起者,它的下层是依赖于AFNetworking。并且,也是一个单例类。
这里应该是延续上面的第5步操作:
5.1 XMEngine对象拿到request对象,通过request的属性,确认请求方式是上传、下载还是普通请求、请求方法、序列化方式、超时时间、业务参数以及全局参数(Header、agent等),并使用AFHTTPRequestSerializer 的实例对象 生成NSMutableURLRequest类型的URLRequest。如果出现序列化失败,那么将会直接进入失败的回调函数中。(作者这里处理序列化失败回调时候,使用了一个异步线程)
5.2 调用AFNetkworking 的sessionManager 并且请求飞起来。这其中,通过objc的runtime的 关联对象方法OBJC_EXPORT void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy) 给起飞的请求task将request绑定到了task,算是添加了一个属性吧。
5.3 通过task的identifier,从sessionManager的tasks数组中,找到对应identifier的task,进行改任务的取消操作。这个过程,这这通过 信号量(dispatch_semaphore_...)机制做了线程安全的处理。

总结

对这个轻量级的网络框架分析就差不多这样了,总结一下自己对这个框架的认识:
1、这个框架属于集中型的设计,请求都是通过XMCenter进行调度
2、大量使用了block(简直废话😄),所以有时候看起来的确有点跳,习惯就好了
3、框架也是组织request,request起飞,response落地三步走,所以从这个方向去理解,就容易多了
4、感谢作者的贡献,看源码还是好处多多,学习了!
5、有理解错误的地方,欢迎指正

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,287评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,346评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,277评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,132评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,147评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,106评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,019评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,862评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,301评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,521评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,682评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,405评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,996评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,651评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,803评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,674评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,563评论 2 352

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,651评论 18 139
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,622评论 18 399
  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 10,952评论 6 13
  • 一. Java基础部分.................................................
    wy_sure阅读 3,810评论 0 11
  • AFHTTPRequestOperationManager 网络传输协议UDP、TCP、Http、Socket、X...
    Carden阅读 4,337评论 0 12