iOS NSURLConnection和异步网络请求
在日常应用中,我们往往使用AFNetworking等第三方库来实现网络请求部分。这篇文章会简要地介绍一下如何使用NSURLConnection来进行异步的网络请求。
我们先看一个小demo
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib. NSString *urlStr = @"http://www.baidu.com";
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlStr]]; //从这个试验可以看出,connection的函数在 mainrunloop运行for循环时根本无法被调用,由此可见,这里的connection是在mainThread中运行的。
NSURLConnection *con = [[NSURLConnection alloc] initWithRequest:request delegate:self]; for(int i = ;i<;i++)
{
NSLog(@"%d",i);
} NSLog(@"for end==========");
} - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
NSLog(@"good!!!!!!!!");
}
看下输入
-- ::18.861 UrlConnectionASyncTest[:60b]
-- ::18.862 UrlConnectionASyncTest[:60b]
-- ::18.862 UrlConnectionASyncTest[:60b]
-- ::18.862 UrlConnectionASyncTest[:60b] for end==========
-- ::18.865 UrlConnectionASyncTest[:60b] good!!!!!!!!
查看苹果的文档会发现如下的解释
By default, a connection is scheduled on the current thread in the default mode when it is created. If you create a connection with the initWithRequest:delegate:startImmediately: method and provide NO for the startImmediately parameter, you can instead schedule the connection on an operation queue before starting it with the start method. You cannot reschedule a connection after it has started.
这就是说,如果你仅仅通过在主线程中使用initWithRequest:delegate:方法创建一个connection对象,它会默认地加入到mainThread中,这样当数据返回时,会在main thread中执行,这就会影响UI的刷新。这种connection就是不是同步connection,不同于同步网络请求函数sendSynchronousRequest,但是它的回调函数会在main thread中执行,会影响main thread中的其他函数执行。
下面是官方文档对NSURLConnection请求数据的3中方法的总结:
To retrieve the contents of a URL synchronously: In code that runs exclusively on a background thread, you can call sendSynchronousRequest:returningResponse:error: to perform an HTTP request. This call returns when the request completes or an error occurs. For more details, see Retrieving Data Synchronously. To retrieve the contents of a URL using a completion handler block: If you do not need to monitor the status of a request, but merely need to perform some operation when the data has been fully received, you can call sendAsynchronousRequest:queue:completionHandler:, passing a block to handle the results. For more details, see Retrieving Data Using a Completion Handler Block. To retrieve the contents of a URL using a delegate object: Create a delegate class that implements at least the following delegate methods: connection:didReceiveResponse:, connection:didReceiveData:, connection:didFailWithError:, and connectionDidFinishLoading:. The supported delegate methods are defined in the NSURLConnectionDelegate, NSURLConnectionDownloadDelegate, and NSURLConnectionDataDelegate protocols.
那么如何创建一个在其他thread中执行回调函数的connection呢?系统提供了2套方法,
第一套是使用类方法,sendAsynchronousRequest:queue:completionHandler:
第二套是使用几个对象方法,顺序如下
.使用initWithRequest:delegate:startImmediately:生成一个不立即开始的connnection .通过scheduleInRunLoop:forMode: 或者 setDelegateQueue: 设置回调方法运行的thread,推荐使用第二个。 .调用start开始connection请求。
下面给出一个demo
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib. NSString *urlStr = @"http://www.baidu.com";
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlStr]]; //从这个试验可以看出,connection的函数在 mainrunloop运行for循环时根本无法被调用,由此可见,这里的connection是在mainThread中运行的。
// NSURLConnection *con = [[NSURLConnection alloc] initWithRequest:request delegate:self]; NSURLConnection *con = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO]; [con setDelegateQueue:[[NSOperationQueue alloc] init]];
[con start]; for(int i = ;i<;i++)
{
NSLog(@"%d",i);
} NSLog(@"for end==========");
} - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
// NSLog(@"data is %@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
NSLog(@"good!!!!!!!!");
}
结果如下
-- ::15.129 UrlConnectionASyncTest[:60b]
-- ::15.129 UrlConnectionASyncTest[:60b]
-- ::15.129 UrlConnectionASyncTest[:60b]
-- ::15.129 UrlConnectionASyncTest[:60b]
-- ::15.129 UrlConnectionASyncTest[:60b]
-- ::15.129 UrlConnectionASyncTest[:60b]
-- ::15.130 UrlConnectionASyncTest[:60b]
-- ::15.134 UrlConnectionASyncTest[:] good!!!!!!!!
-- ::15.143 UrlConnectionASyncTest[:60b]
-- ::15.144 UrlConnectionASyncTest[:60b]
-- ::15.144 UrlConnectionASyncTest[:] good!!!!!!!!
-- ::15.144 UrlConnectionASyncTest[:60b]
-- ::15.144 UrlConnectionASyncTest[:60b]
-- ::15.144 UrlConnectionASyncTest[:60b]
-- ::15.145 UrlConnectionASyncTest[:60b]
可以看出connection的回调函数已经不再main thread中执行了!
iOS NSURLConnection和异步网络请求的更多相关文章
- iOS 多个异步网络请求全部返回后再执行具体逻辑的方法
对于dispatch多个异步操作后的同步方法,以前只看过dispatch_group_async,看看这个方法的说明: * @discussion * Submits a block to a dis ...
- iOS开发——post异步网络请求封装
IOS中有许多网络请求的函数,同步的,异步的,通过delegate异步回调的. 在做一个项目的时候,上网看了很多别人的例子,发现都没有一个简单的,方便的异步请求的封装例子.我这里要给出的封装代码,是异 ...
- ios 关于使用异步网络请求时block回调的内存注意
在一个controller中,使用 NSURLSessionDataTask *dataTask = [[NSURLSession sharedSession] dataTaskWithRequest ...
- IOS9中使用NSURLConection发送异步网络请求
IOS9中使用NSURLConection发送异步网络请求 在ios9中,NSURLConection的sendSync..和sendAsync已经过时.被NSURLSession代替. 以下蓝色部分 ...
- Android中的异步网络请求
本篇文章我们来一起写一个最基本的Android异步网络请求框架,借此来了解下Android中网络请求的相关姿势.由于个人水平有限,文中难免存在疏忽和谬误,希望大家可以指出,谢谢大家:) 1. 同步网络 ...
- AJAX其实就是一个异步网络请求
AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML).其实就是一个异步网络请求. 一.创建对象 var xmlhttp; if (w ...
- iOS开发--用户点击频繁,多个异步网络请求取消问题?
一.业务环境描述 当一个view同时添加两个tableView为subView的时候,两个tableView分别为mainTable和subTable. 当用户点击mainTable上的某一条数据时, ...
- iOS 自己封装的网络请求,json解析的类
基本上所有的APP都会涉及网络这块,不管是用AFNetWorking还是自己写的http请求,整个网络框架的搭建很重要. 楼主封装的网络请求类,包括自己写的http请求和AFNetWorking的请求 ...
- iOS 处理多个网络请求的并发的情况
如何处理多个网络请求的并发的情况 一.概念 1.并发 当有多个线程在操作时,如果系统只有一个CPU,则它根本不可能真正同时进行一个以上的线程,它只能把CPU运行时间划分成若干个时间段,再将时间 段分配 ...
随机推荐
- struts2中怎么把action中的值传递到jsp页面
对于如何把struts2的action中的值传到jsp页面中,主要的方法有2种: 使用转发视图利用request域中储存所需的值 使用重定向时存储数据进入session使其在jsp中可以获得 下面,让 ...
- Sqlserver 读取EXCEL
1.1 启用本地读取设置 --启用EXEC sp_configure 'show advanced options', 1RECONFIGUREEXEC sp_configure 'Ad Hoc Di ...
- Hibernate 缓存机制
一.why(为什么要用Hibernate缓存?) Hibernate是一个持久层框架,经常访问物理数据库. 为了降低应用程序对物理数据源访问的频次,从而提高应用程序的运行性能. 缓存内的数据是对物理数 ...
- java初学的分析
java初学的分析第一阶段:入门阶段学习目标:简单项目开发学习内容:1.Java入门书籍,Java基础知识.关于Java入门级的书,给大家推荐过<Java编程思想>.<Java核心技 ...
- Jquery easyui datagrid 删除多行问题
http://www.cnblogs.com/Dtscal/archive/2012/07/04/2576639.html 最近模仿了刘冬大哥的<开源框架完美组合之Spring.NET + NH ...
- log4j使用教程详解(怎么使用log4j2)
1. 去官方下载log4j 2,导入jar包,基本上你只需要导入下面两个jar包就可以了(xx是乱七八糟的版本号): log4j-core-xx.jar log4j-api-xx.jar 2. 导入到 ...
- 大数据分析与机器学习领域Python兵器谱
http://www.thebigdata.cn/JieJueFangAn/13317.html 曾经因为NLTK的缘故开始学习Python,之后渐渐成为我工作中的第一辅助脚本语言,虽然开发语言是C/ ...
- linux下安装phpredis扩展--update20141127
***今天又装了phpredis,更新一下phpredis的下在地址**** 1.下载php所需的模块owlient-phpredis-90ecd17.tar.gz(tar.gz文件下载:owlien ...
- map vs hash_map
1. map, multimap, set, multiset g++ 中 map, multimap, set, multiset 由红黑树实现 map: bits/stl_map.h multim ...
- js ajax 向后台传递数组
//定义数组 var _arrays = []; for (var i = 0; i < 10; i++) { _arrays.push(i); } //post $.post(href, {l ...