在日常应用中,我们往往使用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和异步网络请求的更多相关文章

  1. iOS 多个异步网络请求全部返回后再执行具体逻辑的方法

    对于dispatch多个异步操作后的同步方法,以前只看过dispatch_group_async,看看这个方法的说明: * @discussion * Submits a block to a dis ...

  2. iOS开发——post异步网络请求封装

    IOS中有许多网络请求的函数,同步的,异步的,通过delegate异步回调的. 在做一个项目的时候,上网看了很多别人的例子,发现都没有一个简单的,方便的异步请求的封装例子.我这里要给出的封装代码,是异 ...

  3. ios 关于使用异步网络请求时block回调的内存注意

    在一个controller中,使用 NSURLSessionDataTask *dataTask = [[NSURLSession sharedSession] dataTaskWithRequest ...

  4. IOS9中使用NSURLConection发送异步网络请求

    IOS9中使用NSURLConection发送异步网络请求 在ios9中,NSURLConection的sendSync..和sendAsync已经过时.被NSURLSession代替. 以下蓝色部分 ...

  5. Android中的异步网络请求

    本篇文章我们来一起写一个最基本的Android异步网络请求框架,借此来了解下Android中网络请求的相关姿势.由于个人水平有限,文中难免存在疏忽和谬误,希望大家可以指出,谢谢大家:) 1. 同步网络 ...

  6. AJAX其实就是一个异步网络请求

    AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML).其实就是一个异步网络请求. 一.创建对象 var xmlhttp; if (w ...

  7. iOS开发--用户点击频繁,多个异步网络请求取消问题?

    一.业务环境描述 当一个view同时添加两个tableView为subView的时候,两个tableView分别为mainTable和subTable. 当用户点击mainTable上的某一条数据时, ...

  8. iOS 自己封装的网络请求,json解析的类

    基本上所有的APP都会涉及网络这块,不管是用AFNetWorking还是自己写的http请求,整个网络框架的搭建很重要. 楼主封装的网络请求类,包括自己写的http请求和AFNetWorking的请求 ...

  9. iOS 处理多个网络请求的并发的情况

    如何处理多个网络请求的并发的情况 一.概念 1.并发 当有多个线程在操作时,如果系统只有一个CPU,则它根本不可能真正同时进行一个以上的线程,它只能把CPU运行时间划分成若干个时间段,再将时间 段分配 ...

随机推荐

  1. 【poj3070】 Fibonacci

    http://poj.org/problem?id=3070 (题目链接) 题意 用矩阵乘法求fibonacci数列的第n项. Solution 矩乘入门题啊,题目把题解已经说的很清楚里= =. 矩乘 ...

  2. easyui之datagrid的使用

    http://www.cnblogs.com/ruanmou001/p/3840954.html 一.神马是easyui jQuery EasyUI是一组基于jQuery的UI插件集合,而jQuery ...

  3. app工程构成

    1)工程配置文件: 2)源代码: 3)资源文件.

  4. javascript判断文件大小

    <input type="file" id="fileName" name ="fileName" onchange="Ge ...

  5. nginx proxy超时报错 upstream timed out (110: Connec...

    环境介绍 服务器:centos6.4服务:nginx proxy 问题描述: 然后查找  /opt/usr/nginx/1.4.0/logs  错误 error.log日志提示如下 2015/01/0 ...

  6. Common Pitfalls In Machine Learning Projects

    Common Pitfalls In Machine Learning Projects In a recent presentation, Ben Hamner described the comm ...

  7. hdu 2018 母牛的故事

    #include<stdio.h> int main(void) { int i,n,j,k; long long narr[60]; narr[1]=1; narr[2]=2; narr ...

  8. Repository

    namespace MyRepository.Domain.Infrastructure { public class Repository<TEntity> : IRepository& ...

  9. SSH协议及其应用

    SSH协议及其应用 原文作者:阮一峰 链接: http://www.ruanyifeng.com/blog/2011/12/ssh_remote_login.html http://www.ruany ...

  10. Nginx和PHP-FPM的启动、重启、停止脚本分享(转)

    服务器上的Nginx和PHP都是源码编译安装的,不像ubuntu一样有自带service启动脚本,所以不支持类似以前的nginx (start|restart|stop|reload)了.自己动手丰衣 ...