尽管NSURLConnection已经不建议使用了,iOS 7取而代之的是NSURLSession,但是本文依然打算剖析一下,其中一些思想还是值得学习一下,如果您不用NSURLConnection,并且也不打算尝试使用,可以跳过本文。

一、概念介绍

NSURLConnection是2003年随着第一版Safari的发布而发布的,它不单单是一个网络请求类,而是指代Foundation框架的URL系统中的一系列关联的组件:NSURLRequestNSURLResponseNSURLProtocolNSHTTPCookieStorageNSURLCredentialStorage以及同名类NSURLConnection

1. 异步处理代理

其中,NSURLRequest被传递给NSURLConnection。被委托对象(遵守以前的非正式协议<NSURLConnectionDelegate><NSURLConnectionDataDelegate>)异步返回一个NSURLResponse以及包含服务器返回信息的NSData

2. 请求策略

在一个请求被发送到服务器之前,系统会先查询共享的缓存信息,然后根据策略(policy)以及可用性(availability)的不同,一个已经被缓存的响应可能会被立即返回。如果没有缓存的响应可用,则这个请求将根据我们指定的策略来缓存它的响应以便将来的请求可以使用。

3. 认证策略

在把请求发送给服务器的过程中,服务器可能会发出鉴权查询(authentication challenge),这可以由共享的 cookie 或机密存储(credential storage)来自动响应,或者由被委托对象来响应。发送中的请求也可以被注册的NSURLProtocol对象所拦截,以便在必要的时候无缝地改变其加载行为。

4. 下载过程

NSURLConnection下载文件时,先是将整个文件下载到内存,然后再写入到沙盒,如果文件比较大,就会出现内存暴涨的情况。

二、使用步骤

请求步骤:

  • 设置请求路径
  • 创建请求对象(默认是GET请求,且已经默认包含了请求头)
  • 发送网络请求
  • 接收到服务器的响应后,解析响应体

0.常用代理介绍

/*
1.当接收到服务器响应的时候调用,该方法只会调用一次
第一个参数connection:监听的是哪个NSURLConnection对象
第二个参数response:接收到的服务器返回的响应头信息
*/
- (void)connection:(nonnull NSURLConnection *)connection didReceiveResponse:(nonnull NSURLResponse *)response /*
2.当接收到数据的时候调用,该方法会被调用多次
第一个参数connection:监听的是哪个NSURLConnection对象
第二个参数data:本次接收到的服务端返回的二进制数据(可能是片段)
*/
- (void)connection:(nonnull NSURLConnection *)connection didReceiveData:(nonnull NSData *)data
/* 3.当服务端返回的数据接收完毕之后会调用
通常在该方法中解析服务器返回的数据
*/
-(void)connectionDidFinishLoading:(nonnull NSURLConnection *)connection /*4.当请求错误的时候调用(比如请求超时)
第一个参数connection:NSURLConnection对象
第二个参数:网络请求的错误信息,如果请求失败,则error有值
*/
- (void)connection:(nonnull NSURLConnection *)connection didFailWithError:(nonnull NSError *)error

1. 各种方法请求

  • 方法一:利用sendSynchronousRequest发送GET请求,该请求是同步的
	//1.确定请求路径
NSURL *url = [NSURL URLWithString:@""]; //2.创建一个请求对象
NSURLRequest *request = [NSURLRequest requestWithURL:url]; //3.把请求发送给服务器
//sendSynchronousRequest 阻塞式的方法,会卡住线程 NSHTTPURLResponse *response = nil;
NSError *error = nil; /*
第一个参数:请求对象
第二个参数:响应头信息,当该方法执行完毕之后,该参数被赋值
第三个参数:错误信息,如果请求失败,则error有值
*/
//该方法是阻塞式的,会卡住线程
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]; // 对data进行处理
  • 方法二:利用sendAsynchronousRequest发送POST请求,该请求是异步的
	//1.确定请求路径
NSURL *url = [NSURL URLWithString:@""]; //2.创建一个请求对象
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; // 2.1设置请求方式
// 注意: POST一定要大写
request.HTTPMethod = @"POST";
// 2.2设置请求体
// 注意: 如果是给POST请求传递参数: 那么不需要写?号
request.HTTPBody = [@"username=Mitchell&pwd=123456&type=JSON" dataUsingEncoding:NSUTF8StringEncoding]; //3.把请求发送给服务器,发送一个异步请求
/*
第一个参数:请求对象
第二个参数:回调方法在哪个线程中执行,如果是主队列则block在主线程中执行,非主队列则在子线程中执行
第三个参数: completionHandlerBlock块:接受到响应的时候执行该block中的代码
response:响应头信息
data:响应体
connectionError:错误信息,如果请求失败,那么该参数有值
*/ [NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc]init] completionHandler:^(NSURLResponse * __nullable response, NSData * __nullable data, NSError * __nullable connectionError) { //4.解析服务器返回的数据
NSString *str = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
//转换并打印响应头信息
NSHTTPURLResponse *r = (NSHTTPURLResponse *)response;
}];
  • 方法三:通过设置代理,来处理请求响应或数据
	// 第一种代理方式,自动发送请求
[[NSURLConnection alloc]initWithRequest:request delegate:self]; /*
第一个参数:请求对象
第二个参数:谁成为NSURLConnetion对象的代理
第三个参数:是否马上发送网络请求,如果该值为YES则立刻发送,如果为NO则不会发送网路请求
*/
NSURLConnection *conn = [[NSURLConnection alloc]initWithRequest:request delegate:self startImmediately:NO]; //在startImmediately为NO时,调用该方法控制网络请求的发送
[conn start]; // 第三种代理方式
//设置代理的第三种方式:使用类方法设置代理,会自动发送网络请求
NSURLConnection *conn = [NSURLConnection connectionWithRequest:request delegate:self]; //取消网络请求
//[conn cancel];

2. NSURLConnection 与 NSRunLoop 的关联使用

主要是区分 NSURLConnection 在主线程和子线程发送网络请求的区别

  • 主线程
	// 直接发送网络请求,发送是异步的,但是代理方法是在主线程中执行的
NSURL *url = [NSURL URLWithString:@"http://mvvideo1.meitudata.com/55d99e5939342913.mp4"]; NSURLRequest*request = [NSURLRequest requestWithURL:url];
//这里分两种方式发送请求
//2.1 直接发送网络请求是异步的,但是回调方法是在主线程中执行的
//[[NSURLConnection alloc]initWithRequest:request delegate:self]; // 如果按照如下设置,那么回调的代理方法也会运行在子线程中
NSURL*url = [NSURL URLWithString:@"http://mvvideo1.meitudata.com/55d99e5939342913.mp4"];
NSURLRequest*request = [NSURLRequest requestWithURL:url];
//2.2 设置回调方法也在子线程中运行
NSURLConnection*conn = [[NSURLConnection alloc]initWithRequest:request delegate:self startImmediately:NO];
[conn setDelegateQueue:[[NSOperationQueue alloc] init]];
[conn start];
  • 子线程

因为 NSURLConnection 是局部变量,当我们创建的时候其实是会默认添加到当前的 RunLoop 中,如果是在主线程添加,主线程的 RunLoop 是默认有的,无须我们创建;然而如果在子线程中,是默认没有 RunLoop 和输入源的,所以需要给子线程手动添加 RunLoop

调用start 方法时,如果没有 RunLoop ,会默认添加一个 RunLoop 到当前的线程中来,然后将connection加到runLoop中。

dispatch_async(dispatch_get_global_queue(0, 0), ^{

    NSRunLoop *loop = [NSRunLoop currentRunLoop];
[NSURLConnection connectionWithRequest:request delegate:self];
[loop run]; // 下面这样无法发送请求
[NSURLConnection connectionWithRequest:request delegate:self];
});

至此,NSURLConnection的简介结束,只是提供了最简单应用的参考,如有不足之处,请不吝指教。下一篇简介目前推荐应用的NSURLSession,敬请期待......

参考文档

http://www.jianshu.com/p/056b1817d25a

http://www.jianshu.com/p/982a3035c93a

http://www.jianshu.com/p/63e2ad28459f

http://www.jianshu.com/p/f291ee58c012

NSURLConnection从入门到放弃的更多相关文章

  1. CYQ.Data 从入门到放弃ORM系列:开篇:自动化框架编程思维

    前言: 随着CYQ.Data 开始回归免费使用之后,发现用户的情绪越来越激动,为了保持这持续的激动性,让我有了开源的念头. 同时,由于框架经过这5-6年来的不断演进,以前发的早期教程已经太落后了,包括 ...

  2. [精品书单] C#/.NET 学习之路——从入门到放弃

    C#/.NET 学习之路--从入门到放弃 此系列只包含 C#/CLR 学习,不包含应用框架(ASP.NET , WPF , WCF 等)及架构设计学习书籍和资料. C# 入门 <C# 本质论&g ...

  3. OpenStack从入门到放弃

    OpenStack从入门到放弃 目录: 为何选择云计算/云计算之前遇到的问题 什么是云计算 云服务模式 云应用形式 传统应用与云感知应用 openstack及其相关组件介绍 flat/vlan/gre ...

  4. 绕过校园网的共享限制 win10搭建VPN服务器实现--从入门到放弃

    一.开篇立论= =.. 上次说到博主在电脑上搭建了代理服务器来绕过天翼客户端的共享限制,然而经过实际测试还不够完美,所以本着生命不息,折腾不止的精神,我又开始研究搭建vpn服务器= =... (上次的 ...

  5. 《区块链:从入门到放弃》之obc安装步骤

    obc安装步骤 朋友们可能会好奇,厨师不研究菜谱怎么改研究兵法了,哈哈,我原本是app出身,最近被安排去预研区块链和比特币技术,2个月下来,颇有斩获.期间得到IBM的CC同学指导我一步一步安装obc的 ...

  6. win10搭建代理服务器实现绕过校园网的共享限制--从入门到放弃

    博主所在学校特别坑爹,校园网被电信一家垄断了,而且最恶心的还是电信要求一条网线只能供一台电脑上网,不许接路由器共享网络= =- (还有电信2M价格是380+每年,20m是500每年,而且网速都很慢= ...

  7. WPF从入门到放弃系列第二章 XAML

    本文是作者学习WPF从入门到放弃过程中的一些总结,主要内容都是对学习过程中拜读的文章的整理归纳. 参考资料 XAML 概述 (WPF):https://msdn.microsoft.com/zh-cn ...

  8. Android -- 带你从源码角度领悟Dagger2入门到放弃

    1,以前的博客也写了两篇关于Dagger2,但是感觉自己使用的时候还是云里雾里的,更不谈各位来看博客的同学了,所以今天打算和大家再一次的入坑试试,最后一次了,保证最后一次了. 2,接入项目 在项目的G ...

  9. Android -- 带你从源码角度领悟Dagger2入门到放弃(二)

    1,接着我们上一篇继续介绍,在上一篇我们介绍了简单的@Inject和@Component的结合使用,现在我们继续以老师和学生的例子,我们知道学生上课的时候都会有书籍来辅助听课,先来看看我们之前的Stu ...

随机推荐

  1. Chrome浏览器扩展开发系列之九:Chrome浏览器的chrome.alarms.* API

    Chrome浏览器扩展程序通过chrome.alarms.* API,可以制定计划周期性地执行代码,或在指定时间执行代码. 要使用chrome.alarms.* API,首先需要在manifest.j ...

  2. 关于Win7 内存变小处理方法

    windows + R 输入msconfig 点击引导 点击高级选项 点击最大内存打钩,就好了,你重启,你的内存将恢复成原来的.

  3. Spring Security4实例(Java config 版) —— Remember-Me

    本文源码请看这里 相关文章: Spring Security4实例(Java config版)--ajax登录,自定义验证 Spring Security提供了两种remember-me的实现,一种是 ...

  4. 0001.如何在Windows7(x64)上安装 Sharepoint2010 Fundation

    一.修改Config.xml文件 到目录:"C:\Program Files (x86)\MSECache\SharePoint2010\Files\Setup"下去修改confi ...

  5. HTML5 drag和drop的亲手实践

    起因 最近在公司打杂的时候,突然分到了一个锅,就是要支持一个新的功能:用户可以通过拖曳组件来改变组件的顺序.因此,这阵子就看了一下网上的一些drag和drog的文章以及W3C的介绍,然后自己亲手实践了 ...

  6. java三大框架介绍

    常听人提起三大框架,关于三大框架,做了如下了解: 三大框架:Struts+Hibernate+Spring java三大框架主要用来做WEN应用. Struts主要负责表示层的显示 Spring利用它 ...

  7. python基础(7):元祖类型(赋值补充)

    前面学了列表和字典,今天我们看一个和列表相似的类型元祖. 预习: 简单购物车 实现打印商品详细信息,用户输入商品名和购买个数,则将商品名,价格,购买个数加入购物列表,如果输入为空或其他非法输入则要求用 ...

  8. jenkins外网slave配置

    背景: 客户提供了测试服务器,但不能外网直连需要通过windows跳板进行进行连接. 方案设定将windows跳板机配置为远程slave节点. 技术支持: jenkins-slave  windows ...

  9. VerilogHDL概述与数字IC设计流程学习笔记

    一.HDL的概念和特征 HDL,Hard Discrimination Language的缩写,翻译过来就是硬件描述语言.那么什么是硬件描述语言呢?为什么不叫硬件设计语言呢?硬件描述语言,顾名思义就是 ...

  10. shell 脚本编写 if else then

    if ....; then .... elif ....; then .... else .... fi 大多数情况下,可以使用测试命令来对条件进行测试.比如可以比较字符串.判断文件是否存在及是否可读 ...