很多时候,AFNetworking都是目前iOS开发者网络库中的不二选择。Github2W+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,然后将相关的requestSerializerreponseSerializer赋值;最后发起相应的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

  NSURLSessioniOS7.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著称。如下图,对相同图片、相同服务器的下载,在不同协议下所需的时间:

http2

  这里我们并不打算展开HTTP /2的原理,有兴趣的同学可以Google之。根据2015的WWDC Session711,我们知道iOS9+NSURLSession开始正式支持HTTP /2,也就意味着你的网络连接速度也可以有如上图那样的提升。

  更人性化更优秀的API设计,HTTP /2的支持,这是否能成为你使用NSURLSession的理由?至少它们成为了说服我的理由。

为什么要尽量共享Session,而不是每次新建Session

  在回答这个问题以前,我们先来聊聊网络的通讯协议。我们也都知道,HTTP协议是基于TCP协议的。所以在每次的HTTP请求之前,客户端和服务器端,都先需要经过TCP连接的三次握手,即每次请求之前,网络的数据都已经在客户端和服务器端之间来回了三次。如下图:

TCP三次握手(图片来源于网络)

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

抓包

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

非共享Session

共享Session

  聊到这里,本章提出的问题,其实答案已经逐渐明了了。没错,共享的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服务器的并发最大为4OS X6。而如果你没有使用共享的Session,则可能会超过这个数。

  因此,如果能用共享的Session,还是用共享的吧。有些许的网络加速,也是一件不错的事情,您说呢?

参考链接:
1.http://www.jianshu.com/p/5969bbb4af9f

2.http://www.jianshu.com/p/a9bca62d8dab

共享AFHTTPSessionManager 单例好处浅析的更多相关文章

  1. qt 共享内存 单例

        QT 进程间通信之古老的方法(内存共享)     让QT只运行一个实例     以上两篇文章中分别讲述了QSharedMemory的不同作用,第一篇讲了进程间通信,第二篇讲述了怎么让应用程序只 ...

  2. iOS 如何创建单例对象

    一.什么是单例? 说到单例我就想起了我的java啊 ,不禁感叹起我的大学时光,学了4年的java开发,到现在还是放弃了我的java,踏入了iOS的行列. 算了,入正轨,我现在正是铁树银花的青春美少女, ...

  3. 设计模式的征途—1.单例(Singleton)模式

    单例模式属于创建型模式的一种,创建型模式是一类最常用的设计模式,在软件开发中应用非常广泛.创建型模式将对象的创建和使用分离,在使用对象时无需关心对象的创建细节,从而降低系统的耦合度,让设计方案更易于修 ...

  4. 一个单例(Singleton),并说明单例的目的和好处

    单例的目的:保证一个类只有单一的实例,也就是说你无法通过new来创建这个类的一个新实例. 单例的好处:当一个对象在程序内部只能有一个实例的时候,它可以保证我们不会重复创建,而是始终指向同一个对象. S ...

  5. 七、单例设计模式共享数据分析、解决、call_once

    一.设计模式大概谈 代码的一些写法,与常规的写法不太一样,程序灵活,维护起来很方便,但是别人接管.阅读代码很痛苦. 用设计模式理念写出来的代码很晦涩.<< head first>&g ...

  6. C++并发与多线程学习笔记--单例设计模式、共享数据分析

    设计模式 共享数据分析 call_once 设计模式 开发程序中的一些特殊写法,这些写法和常规写法不一样,但是程序灵活,维护起来方便,别人接管起来,阅读代码的时候都会很痛苦.用设计模式理念写出来的代码 ...

  7. 《JAVA笔记 day08 静态_单例》

    //static关键字: /* 静态方法的使用注意事项: 1,静态方法不能访问非静态的成员. 但是非静态是可以访问静态成员的. 说明:静态的弊端在于访问出现了局限性.好处是可以直接别类名调用. 2,静 ...

  8. Spring单例与线程安全小结

    一.Spring单例模式与线程安全   Spring框架里的bean,或者说组件,获取实例的时候都是默认的单例模式,这是在多线程开发的时候要尤其注意的地方. 单例模式的意思就是只有一个实例.单例模式确 ...

  9. 【转】Spring Bean单例与线程安全

    一.Spring单例模式及线程安全 Spring框架中的Bean,或者说组件,获取实例的时候都是默认单例模式,这是在多线程开发的时候需要尤其注意的地方. 单例模式的意思是只有一个实例,例如在Sprin ...

随机推荐

  1. 模拟Vue之数据驱动5

    一.前言 在"模拟Vue之数据驱动4"中,我们实现了push.pop等数组变异方法. 但是,在随笔末尾我们提到,当pop.sort这些方法触发后,该怎么办呢?因为其实,它们并没有往 ...

  2. 轻松搞定javascript日期格式化问题

    Date.prototype.format = function(f){ var d = this f = f || "yyyy-MM-dd hh:mm:ss" return f. ...

  3. Js-Html 前端系列--显示有格式的文本

    var dp = $("#dp").val(); var dpXSS = filterXss(dp); document.getElementById("descript ...

  4. ASP.NET Zero--7.控制器加权限

    上次已经实现了菜单权限的配置,达到了不同角色的用户显示不同的菜单.但这里还有BUG,如果你直接访问http://localhost:8019/Mpa/Test这个控制器时,并使用"Defau ...

  5. jsp-4 用cookie实现记住密码

    jsp-4 用cookie实现记住密码 这次就有点简单了 基本是jsp-3的代码但是有些修改 public void login(HttpServletRequest req, HttpServlet ...

  6. docker--------------实践(转载)

    在私有云的容器化过程中,我们并不是白手起家开始的.而是接入了公司已经运行了多年的多个系统,包括自动编译打包,自动部署,日志监控,服务治理等等系统.在容器化之前,基础设施主要以物理机和虚拟机为主.因此, ...

  7. java基础练习 9

    import java.util.Scanner; public class Ninth { /*取一个整数a从右端开始的4-7位.*/ public static void main(String[ ...

  8. Date类型常用概念及方法总结(1)

      Date类型使用UTC(国际协调时间)1970年1月1日零时开始经过的毫秒数来保存时间. (1)创建当前日期           调用Date不传递参数的情况下,创建的新对象自动获得当前日期和时间 ...

  9. List转换为DataTable

    public static DataTable ListToDataTable(IList list) { DataTable result = new DataTable(); if (list.C ...

  10. js实现浏览器通知功能

    概述 Notification API是浏览器的通知接口,用于在用户的桌面(而不是网页上)显示通知信息,桌面电脑和手机都适用,比如通知用户收到了一封Email.具体的实现形式由浏览器自行部署,对于手机 ...