共享AFHTTPSessionManager 单例好处浅析
很多时候,AFNetworking都是目前iOS
开发者网络库中的不二选择。Github
上2W+
的star
数足见其流行程度。而从iOS7.0
开始,苹果推出了新的网络库继承者NSURLSession
后,AFNetworking
也毫不犹豫地加入了对其的支持。3.0+
更加只是提供了NSURLSession
的支持。
我们使用AFNetworking
的时候,可能会有很多的朋友都会采用以下的写法:
AFHTTPSessionManager *sessionManager = [AFHTTPSessionManager manager];
sessionManager.requestSerializer = [AFHTTPRequestSerializer serializer];
sessionManager.responseSerializer = [AFHTTPResponseSerializer serializer];
[sessionManager GET:urlString
parameters:parameters
progress:progressBlock
success:successHandler
failure:failureHandler];
大概可以描述一下这个过程,每次开启一个网络请求时,首先新建一个AFHTTPSessionManager
,然后将相关的requestSerializer
和reponseSerializer
赋值;最后发起相应的GET/POST
等请求。
而如果是直接采用NSURLSession
来请求网络呢,我们则经常会采用以下的写法:
NSURLSession *session = [NSURLSession
sessionWithConfiguration:
[NSURLSessionConfiguration defaultSessionConfiguration]
delegate:nil
delegateQueue:[NSOperationQueue mainQueue]];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
completionHandler:completionHandler];
[dataTask resume];
这个过程其实和上面的基本一致。新建一个Session
,然后新建task
,激活task
,完成网络请求。
那么现在问题来了。为什么每次都需要新建一个SessionManager/Session
?如果在多个Task
请求的情况下,如果采取一个共享的SessionManager/Session
是否可行?如果可行,与之前每次新建SessionManager/Session
相比,孰优孰劣?
本篇文章会告诉您:
1. 为什么要使用NSURLSession而不是NSURLConnection
2. 为什么要用共享的SessionManager/Session
,而不是每次都启动一个新的
为什么要选择NSURLSession
NSURLSession
在iOS7.0
时被Apple提出后,虽然Apple一直对其良好的API
设计大力推广,然而其能够达到的效果,似乎一直都和NSURLConnection
不相伯仲。
特别是在网络的Dependecy
依赖处理上,由于AFNetworking
优秀的架构设计,NSURLSession
甚至还不如NSURLConnection
好用。那么,有什么理由切换到NSURLSession
? 2015年的WWDC似乎告诉了我们答案。
HTTP /2
, 2015年5月RFC 7540正式发表的下一代HTTP协议,是1999年来HTTP 1.1
发布后的首个更新。相对于前一个版本,HTTP /2
以快
著称。如下图,对相同图片、相同服务器的下载,在不同协议下所需的时间:

这里我们并不打算展开HTTP /2
的原理,有兴趣的同学可以Google之。根据2015的WWDC Session711,我们知道iOS9+
,NSURLSession
开始正式支持HTTP /2
,也就意味着你的网络连接速度也可以有如上图那样的提升。
更人性化更优秀的API
设计,HTTP /2
的支持,这是否能成为你使用NSURLSession
的理由?至少它们成为了说服我的理由。
为什么要尽量共享Session,而不是每次新建Session
在回答这个问题以前,我们先来聊聊网络的通讯协议。我们也都知道,HTTP
协议是基于TCP
协议的。所以在每次的HTTP
请求之前,客户端和服务器端,都先需要经过TCP
连接的三次握手,即每次请求之前,网络的数据都已经在客户端和服务器端之间来回了三次。如下图:

事实上在HTTP 0.9
, HTTP 1.0
协议的时代,每次HTTP的请求,都需要先经过TCP
的连接,然后才开始HTTP
的请求,这样一个流程图,我们可以通过抓包看到:

那么,为了让我们的请求更快,避免每次都产生一个TCP
三次握手,成了一个优化的选项。于是在HTTP 1.1
中,出现了Connection: keep-alive
这个选项。这个优化选项,可以使得客户端和服务器端复用一个TCP
连接,从而减小每次的网络请求时间。


聊到这里,本章提出的问题,其实答案已经逐渐明了了。没错,共享的Session
将会复用TCP
的连接,而每次都新建Session
的操作将导致每次的网络请求都开启一个TCP
的三次握手。
从上面两张图,我们可以清晰地看到,同样都是两次HTTP请求,共享Session
的代码在第二次网络请求时少了TCP
的三次握手的过程。即加速了整个网络的请求时间。
事实上,苹果的文档中,还对一个服务器最高的TCP
并发有相应的描述:
HTTPMaximumConnectionsPerHost Property
The maximum number of simultaneous connections to make to a given host.
Declaration
SWIFT
var HTTPMaximumConnectionsPerHost: Int
OBJECTIVE-C
@property NSInteger HTTPMaximumConnectionsPerHost
Discussion
This property determines the maximum number of simultaneous connections made to each host by tasks within sessions based on this configuration.
This limit is per session, so if you use multiple sessions, your app as a whole may exceed this limit. Additionally, depending on your connection to the Internet, a session may use a lower limit than the one you specify.
The default value is 6 in OS X, or 4 in iOS.
Availability
Available in iOS 7.0 and later.
我们可以看到,默认配置下,iOS
对于同一个IP服务器的并发最大为4
,OS X
为6
。而如果你没有使用共享的Session
,则可能会超过这个数。
因此,如果能用共享的Session
,还是用共享的吧。有些许的网络加速,也是一件不错的事情,您说呢?
Networking with NSURLSession - WWDC 2015 - Videos - Apple Developer
HTTP/2
共享AFHTTPSessionManager 单例好处浅析的更多相关文章
- qt 共享内存 单例
QT 进程间通信之古老的方法(内存共享) 让QT只运行一个实例 以上两篇文章中分别讲述了QSharedMemory的不同作用,第一篇讲了进程间通信,第二篇讲述了怎么让应用程序只 ...
- iOS 如何创建单例对象
一.什么是单例? 说到单例我就想起了我的java啊 ,不禁感叹起我的大学时光,学了4年的java开发,到现在还是放弃了我的java,踏入了iOS的行列. 算了,入正轨,我现在正是铁树银花的青春美少女, ...
- 设计模式的征途—1.单例(Singleton)模式
单例模式属于创建型模式的一种,创建型模式是一类最常用的设计模式,在软件开发中应用非常广泛.创建型模式将对象的创建和使用分离,在使用对象时无需关心对象的创建细节,从而降低系统的耦合度,让设计方案更易于修 ...
- 一个单例(Singleton),并说明单例的目的和好处
单例的目的:保证一个类只有单一的实例,也就是说你无法通过new来创建这个类的一个新实例. 单例的好处:当一个对象在程序内部只能有一个实例的时候,它可以保证我们不会重复创建,而是始终指向同一个对象. S ...
- 七、单例设计模式共享数据分析、解决、call_once
一.设计模式大概谈 代码的一些写法,与常规的写法不太一样,程序灵活,维护起来很方便,但是别人接管.阅读代码很痛苦. 用设计模式理念写出来的代码很晦涩.<< head first>&g ...
- C++并发与多线程学习笔记--单例设计模式、共享数据分析
设计模式 共享数据分析 call_once 设计模式 开发程序中的一些特殊写法,这些写法和常规写法不一样,但是程序灵活,维护起来方便,别人接管起来,阅读代码的时候都会很痛苦.用设计模式理念写出来的代码 ...
- 《JAVA笔记 day08 静态_单例》
//static关键字: /* 静态方法的使用注意事项: 1,静态方法不能访问非静态的成员. 但是非静态是可以访问静态成员的. 说明:静态的弊端在于访问出现了局限性.好处是可以直接别类名调用. 2,静 ...
- Spring单例与线程安全小结
一.Spring单例模式与线程安全 Spring框架里的bean,或者说组件,获取实例的时候都是默认的单例模式,这是在多线程开发的时候要尤其注意的地方. 单例模式的意思就是只有一个实例.单例模式确 ...
- 【转】Spring Bean单例与线程安全
一.Spring单例模式及线程安全 Spring框架中的Bean,或者说组件,获取实例的时候都是默认单例模式,这是在多线程开发的时候需要尤其注意的地方. 单例模式的意思是只有一个实例,例如在Sprin ...
随机推荐
- hive 不同用户 权限设置 出错处理
今天安装了hive 在a账号安装的,一切正常 但是到其他账户下,报错 >show tables; Error in metadata: java.lang.RuntimeException: U ...
- 最近学习了下BI(商业智能)做报表
最近公司购买了Style intelligence 出的BI报表工具,接触新的东西不是很容易上手,这个东西是别的项目组用的,我们项目组由于进度比较快就让我先到他们项目组帮他们,为了使用这个东西,他们已 ...
- linux常见笔试题
一.填空题: 1. 在Linux系统中,以 文件 方式访问设备 . 2. Linux内核引导时,从文件 /etc/fstab 中读取要加载的文件系统. 3. Linux文件系统中每个文件用 i节点 来 ...
- 获取Exception的详细信息
转自:http://blog.csdn.net/long95wang/article/details/8089489 方法一: public static String getExceptionAll ...
- 查增删改MySQL数据库固定模式
省略相关包的导入... public class Base { public static Connection connection = null; public static PreparedSt ...
- jndi 与 jdbc
现在开发中经常用到数据库的两种配置1 jdbc2 jndi 一般开发环境都会使用jdbc环境,自己弄配置方便.但是测试和生产环境一般都使用jndi方式.原因有:1 使用jndi方式配置,数据库的 ...
- Linux下gcc,g++,gdb,scon部分用法笔记
1 Ubuntu下编译安装GCC-4.1.2 拷贝gcc-4.1.2.tar.bz2(我下载的压缩文件)到/usr/local/src 解压 新生成的gcc-4.1.2这个目录被称为源目录,用${sr ...
- List list = new ArrayList()
方便以后扩展List是一个接口,而ArrayList 是一个类. ArrayList 继承并实现了List.List list = new ArrayList();这句创建了一个ArrayList的对 ...
- [转载]We Recommend a Singular Value Decomposition
原文:http://www.ams.org/samplings/feature-column/fcarc-svd Introduction The topic of this article, the ...
- intellij idea 生成UUID
Intellij IDEA 默认没启用这个功能 需要手动设置一下 , 下面是路径 Setting->Inspections->Serialization issues->Serial ...