1、AFNetworking 2.0 和3.0 的区别
-
AFNetworking在3.0版本中删除了基于 NSURLConnection API的所有支持。如果你的项目以前使用过这些API,建议您立即升级到基于 NSURLSession 的API的AFNetworking的版本。
-
AFNetworking 3.0现已完全基于NSURLSession的API,这降低了维护的负担,同时支持苹果增强关于NSURLSession提供的任何额外功能。
-
可以结合MBProgressHUD,网络请求时间短的话,就可以不要显示HUD,提高用户体验,另外HUD也可以懒加载,全程只需要一个HUD即可。HUD内部有创建HUD对象时涉及到请求时间的类方法,在这个方法中如果请求时间小于某个值,就返回nil,即不显示HUD。此外AFN还有联网检测功能,每次请求网络之前先检测有没有网络,没有网络则提示用户(涉及到AFN和HUD的组合封装)
2、NSURLSession和NSURLConnection区别
NSURLConnection
随ios7一起发布,是对NSURLConnection
进行了重构优化后的新的网络访问接口。从iOS9.0开始, NSURLConnection
中发送请求的两个方法已过期(同步请求,异步请求),苹果官方不再推荐使用。下面就将NSURLConnection
与NSURLSession
的区别进行简单的对比。
- 普通任务和上传
NSURLSession
针对下载/上传等复杂的网络操作提供了专门的解决方案,针对普通、上传和下载分别对应三种不同的网络请求任务:NSURLSessionDataTask, NSURLSessionUploadTask
和NSURLSessionDownloadTask.
。创建的task都是挂起状态,需要resume
才能执行。
当服务器返回的数据较小时,NSURLSession
与NSURLConnection
执行普通任务的操作步骤没有区别。
执行上传任务时,NSURLSession
与NSURLConnection
一样同样需要设置POST请求的请求体进行上传。
2.下载任务方式
NSURLConnection
下载文件时,先将整个文件下载到内存,然后再写入沙盒,如果文件比较大,就会出现内存暴涨的情况。而使用NSURLSessionUploadTask
下载文件,会默认下载到沙盒中的tem
文件夹中,不会出现内存暴涨的情况,但在下载完成后会将tem中的临时文件删除,需要在初始化任务方法时,在completionHandler
回调中增加保存文件的代码。
3.请求方法的控制
NSURLConnection
实例化对象,实例化开始,默认请求就发送(同步发送),不需要调用start
方法。而cancel
可以停止请求的发送,停止后不能继续访问,需要创建新的请求。
NSURLSession
有三个控制方法,取消(cancel
),暂停(suspend
),继续(resume
),暂停后可以通过继续恢复当前的请求任务。
4.断点续传的方式
NSURLConnection
进行断点下载,通过设置访问请求的HTTPHeaderField
的Range
属性,开启运行循环,NSURLConnection
的代理方法作为运行循环的事件源,接收到下载数据时代理方法就会持续调用,并使用NSOutputStream
管道流进行数据保存。
NSURLSession
进行断点下载,当暂停下载任务后,如果 downloadTask
(下载任务)为非空,调用 cancelByProducingResumeData:(void (^)(NSData *resumeData))completionHandler
这个方法,这个方法接收一个参数,完成处理代码块,这个代码块有一个NSData
参数 resumeData
,如果 resumeData
非空,我们就保存这个对象到视图控制器的 resumeData 属性中。在点击再次下载时,通过调用[ [self.session downloadTaskWithResumeData:self.resumeData]resume]
方法进行继续下载操作。
经过以上比较可以发现,使用NSURLSession进行断点下载更加便捷。
关于网络请求
iOS 中,关于网络请求的接口自下至上有如下几层:
CFSocket
CFNetwork ->ASIHttpRequest
NSURLConnection ->AFNetworking
NSURLSession ->AFNetworking2, Alamofire
• CFSocket 是最底层的接口,只负责 socket 通信。
• CFNetwork 是基于 CFSocket 等接口的上层封装,ASIHttpRequest 工作于这一层。
• NSURLConnection 是基于 CFNetwork 的更高层的封装,提供面向对象的接口,AFNetworking 工作于这一层。
• NSURLSession 是 iOS7 中新增的接口,表面上是和 NSURLConnection 并列的,但底层仍然用到了 NSURLConnection 的部分功能 (比如 com.apple.NSURLConnectionLoader 线程),AFNetworking2 和 Alamofire 工作于这一层。
下面主要介绍下 NSURLConnection 的工作过程。
通常使用 NSURLConnection 时,你会传入一个 Delegate,当调用了 [connection start] 后,这个 Delegate 就会不停收到事件回调。实际上,start 这个函数的内部会会获取 CurrentRunLoop,然后在其中的 DefaultMode 添加了4个 Source0 (即需要手动触发的Source)。CFMultiplexerSource 是负责各种 Delegate 回调的,CFHTTPCookieStorage 是处理各种 Cookie 的。
当开始网络传输时,我们可以看到 NSURLConnection 创建了两个新线程:com.apple.NSURLConnectionLoader 和 com.apple.CFSocket.private。其中 CFSocket 线程是处理底层 socket 连接的。NSURLConnectionLoader 这个线程内部会使用 RunLoop 来接收底层 socket 的事件,并通过之前添加的 Source0 通知到上层的 Delegate。
图片.png
NSURLConnectionLoader 中的 RunLoop 通过一些基于 mach port 的 Source 接收来自底层 CFSocket 的通知。当收到通知后,其会在合适的时机向 CFMultiplexerSource 等 Source0 发送通知,同时唤醒 Delegate 线程的 RunLoop 来让其处理这些通知。CFMultiplexerSource 会在 Delegate 线程的 RunLoop 对 Delegate 执行实际的回调。