在日常应用中,我们往往使用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. Freemarker-数字默认格式化问题

    freemarker在解析数据格式的时候,默认将数字按3位来分割 例如1000被格式化为1,000 这样做看似美观,但在实际操作时候会带来问题.例如我一个页面有一个元素,该元素的值由后台绑定且超过10 ...

  2. 【HDU 4150】Powerful Incantation

    题 题意 给你s1,s2两个字符串,求s1中有多少个s2 代码 #include<stdio.h> #include<string.h> int t,len1,len2,pos ...

  3. BZOJ-1878 HH的项链 树状数组+莫队(离线处理)

    1878: [SDOI2009]HH的项链 Time Limit: 4 Sec Memory Limit: 64 MB Submit: 2701 Solved: 1355 [Submit][Statu ...

  4. NOIP2013 货车运输 (最大生成树+树上倍增LCA)

    死磕一道题,中间发现倍增还是掌握的不熟 ,而且深刻理解:SB错误毁一生,憋了近2个小时才调对,不过还好一遍AC省了更多的事,不然我一定会疯掉的... 3287 货车运输 2013年NOIP全国联赛提高 ...

  5. HDU 1054 Strategic Game(最小点覆盖+树形dp)

    题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=106048#problem/B 题意:给出一些点相连,找出最小的点数覆盖所有的 ...

  6. POJ 2481Cows(树状数组 + 好题)

    Cows Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 15222   Accepted: 5070 Description ...

  7. CustomerConfigHelper

    public static class CustomerConfigHelper { public static object _lockObject = new object(); private ...

  8. node-js访问rest api的方法

    //npm install node-rest-client --save-dev var Client = require('node-rest-client').Client function l ...

  9. WIN 2003服务器终极安全及问题解决方案

    一.硬盘分区与操 作系统的安装硬盘分区 总的来讲在硬盘分区上面没什么值得深入剖析的地方,无非就是一个在分区前做好规划知道要去放些什么东西, 如果实在不知 道.那就只一个硬盘只分一个区,分区要一次性完成 ...

  10. SQL Server 2005 发布 订阅 (配置实例[图])(转载)

    2.1          发布&订阅 1.       测 试环境: Item 发布机 A 订阅机 B OS Windows 2003 Server Windows 2003 Server S ...