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运行时间划分成若干个时间段,再将时间 段分配 ...
随机推荐
- 【UVA 401】BUPT 2015 newbie practice #2 div2-B-Palindromes
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=102419#problem/B A regular palindrome is a str ...
- MyEclipse10中导入的jquery文件报错(出现红叉叉,提示语法错误)
为了做一个页面特效,导入了一个jQuery文件,怎想,myeclipse竟然报错说是语法错误,但是这个js文件我是从官网上下载的,不应该出错才对,百度谷歌之后终于找到了解决办法: 选中报错的js文件, ...
- CSU 1113 Updating a Dictionary
传送门 Time Limit: 1000MS Memory Limit: 131072KB 64bit IO Format: %lld & %llu Description In th ...
- jQueryEasyUI DateBox的基本使用
http://www.cnblogs.com/libingql/archive/2011/09/25/2189977.html 1.基本用法 代码: 1 2 3 4 5 6 7 8 9 10 11 1 ...
- 异步httpCilent框架post提交到服务器
1 导入AsyncHttPclient框架包下的类: 2在主方法写上这代码即可实现post请求:
- $.ajax返回的JSON格式的数据后无法执行success的解决方法
近段时间做项目,在项目使用了ajax技术,遇到了一个奇怪的问题:"$.ajax返回的JSON格式的数据无法执行success",代码是这样写的: 1 $.ajax({ 2 .. 3 ...
- Win7下JDK环境变量的设置
JDK并不像Microsoft阵营vs那样智能,安装好后所有的东西都给你配置好了,我们还没需要手动配置很多东西 首先说为什么要配置JDK的环境变量在任何路径下识别java命令和java类 配置分为2个 ...
- truncate的用法
truncate是文件处理中的截断函数,今天是有个需求改动了json中的某个值,然后用改动后的值去覆盖之前的数据,这个方法有很多,比如边读边写,然后使用os模块替换,这个适合用于在程序和文件都在同一个 ...
- day4作业之信息表
实在是太low了,终究是自己写的,记录下 #!/usr/bin/env python # coding=utf8 import os, re #这里我把查询这块分为3个函数了,纠结了很久是放一起还是分 ...
- myBatis 实现用户表增删查改操作<方法1 没有使用接口的>(最终版)
在UserMapper.xml中添加增删改查 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYP ...