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 = 0 ;i<10000;i++)
{
NSLog(@"%d",i);
}

NSLog(@"for end==========");
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
NSLog(@"good!!!!!!!!");
}

看下输入

2014-05-05 10:34:18.861 UrlConnectionASyncTest[9988:60b] 9997
2014-05-05 10:34:18.862 UrlConnectionASyncTest[9988:60b] 9998
2014-05-05 10:34:18.862 UrlConnectionASyncTest[9988:60b] 9999
2014-05-05 10:34:18.862 UrlConnectionASyncTest[9988:60b] for end==========
2014-05-05 10:34:18.865 UrlConnectionASyncTest[9988: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的刷新。这种connnection不是同步的connection,因为它在没有得到数据时就可以继续执行其他代码,但也不是那种真正的异步connection,因为它的回调函数会在main
thread中执行,会影响main thread中的其他函数执行。

那么如何创建一个在其他thread中执行回调函数的connection呢?系统提供了2套方法,

第一套是使用类方法,sendAsynchronousRequest:queue:completionHandler:

第二套是使用几个对象方法,顺序如下

1.使用initWithRequest:delegate:startImmediately:生成一个不立即开始的connnection

2.通过scheduleInRunLoop:forMode: 或者 setDelegateQueue: 设置回调方法运行的thread,推荐使用第二个。

3.调用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 = 0 ;i<10000;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!!!!!!!!");
}

结果如下


2014-05-05 11:23:15.129 UrlConnectionASyncTest[10147:60b] 344
2014-05-05 11:23:15.129 UrlConnectionASyncTest[10147:60b] 345
2014-05-05 11:23:15.129 UrlConnectionASyncTest[10147:60b] 346
2014-05-05 11:23:15.129 UrlConnectionASyncTest[10147:60b] 347
2014-05-05 11:23:15.129 UrlConnectionASyncTest[10147:60b] 348
2014-05-05 11:23:15.129 UrlConnectionASyncTest[10147:60b] 349
2014-05-05 11:23:15.130 UrlConnectionASyncTest[10147:60b] 350
2014-05-05 11:23:15.134 UrlConnectionASyncTest[10147:4207] good!!!!!!!!
2014-05-05 11:23:15.143 UrlConnectionASyncTest[10147:60b] 351
2014-05-05 11:23:15.144 UrlConnectionASyncTest[10147:60b] 352
2014-05-05 11:23:15.144 UrlConnectionASyncTest[10147:4207] good!!!!!!!!
2014-05-05 11:23:15.144 UrlConnectionASyncTest[10147:60b] 353
2014-05-05 11:23:15.144 UrlConnectionASyncTest[10147:60b] 354
2014-05-05 11:23:15.144 UrlConnectionASyncTest[10147:60b] 355
2014-05-05 11:23:15.145 UrlConnectionASyncTest[10147:60b] 356

可以看出connection的回调函数已经不再main thread中执行了!

iOS NSURLConnection和异步网络请求

时间: 2025-01-02 14:36:04

iOS NSURLConnection和异步网络请求的相关文章

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

IOS中有许多网络请求的函数,同步的,异步的,通过delegate异步回调的. 在做一个项目的时候,上网看了很多别人的例子,发现都没有一个简单的,方便的异步请求的封装例子.我这里要给出的封装代码,是异步的,post的请求方式.通过ios的原生函数简单封装.通过这个封装可以方便的访问http服务器,获取数据,也可以容易的异步加载网络图片. 首先新建一个httpHelper类,在这个类里进行封装,封装的函数名称就叫做post,参数有请求的地址url,请求的参数params,返回数据后回调的函数blo

NSURLConnection实现异步网络请求

第一步:遵守协议NSURLConnectionDataDelegate 第二步:创建包含请求网址的NSURL类型的对象 NSURL * url = [NSURL URLWithString:PATH]; 第三步:创建NSURLRequest请求 NSURLRequest * request = [NSURLRequest requestWithURL:url]; 第四步:将request对象赋给NSURLCon对象开始异步请求 [NSURLConnection connectionWithReq

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

先看一段错误的方法: - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. NSURLSession *session = [NSURLSession sharedSession]; dispatch_queue_t dispatchQueue = dispatch_queue_create("test.queue&qu

iOS开发中的网络请求

今天来说说关于iOS开发过程中的网络请求. 关于网络请求的重要性我想不用多说了吧.对于移动客户端来说,网络的重要性不言而喻.常见的网络请求有同步GET, 同步POST, 异步GET, 异步POST.今天来看一下四种网络请求的实现方式. 一.同步GET // 1.将网址初始化成一个OC字符串对象 NSString *urlStr = [NSString stringWithFormat:@"%@?query=%@&region=%@&output=json&ak=6E823

iOS 开发 把握AFNet网络请求完成的正确时机

前言 对于iOS开发中的网络请求模块,AFNet的使用应该是最熟悉不过了,但你是否把握了网络请求正确的完成时机?本篇文章涉及线程同步.线程依赖.线程组等专用名词的含义,若对上述名词认识模糊,可先进行查阅理解后阅读本文.如果你也纠结于文中所述问题,可进行阅读希望对你有所帮助.大神无视勿喷. 在真实开发中,我们通常会遇到如下问题: 一.某界面存在多个请求,希望所有请求均结束才进行某操作. 对于这一问题的解决方案很容易想到通过线程组进行实现.代码如下: 1 2 3 4 5 6 7 8 9 10 11

Android中的异步网络请求

本篇文章我们来一起写一个最基本的Android异步网络请求框架,借此来了解下Android中网络请求的相关姿势.由于个人水平有限,文中难免存在疏忽和谬误,希望大家可以指出,谢谢大家:) 1. 同步网络请求 以HTTP的GET请求为例,我们来介绍一下Android中一个基本的同步请求框架的实现.直接贴代码: public class HttpUtils { public static byte[] get(String urlString) { HttpURLConnection urlConne

Github 上Top1的Android 异步网络请求框架

今天给大家分享一个github上Top1的Android异步网络请求框架的使用方法,我给大家分享一个它的基本用法. 先来一个简单的get请求 AsyncHttpClient client = new AsyncHttpClient(); client.get("http://www.google.com", new AsyncHttpResponseHandler() { @Override public void onStart() { // called before reques

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

一.业务环境描述 当一个view同时添加两个tableView为subView的时候,两个tableView分别为mainTable和subTable. 当用户点击mainTable上的某一条数据时,再去发送网络请求subTable中的数据. 存在问题的地方:例如当用户在mainTable上频繁点击各条cell上面的数据时,会出现subTable中数据错乱问题.那么如何取消之前的网络请求呢??? 注:网络请求为异步请求 二.解决方法 1.实例化一个AFHTTPRequestOperationMa

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

基本上所有的APP都会涉及网络这块,不管是用AFNetWorking还是自己写的http请求,整个网络框架的搭建很重要. 楼主封装的网络请求类,包括自己写的http请求和AFNetWorking的请求,代码简单,主要是框架搭建.简单来说,就是一个请求类,一个解析类,还有若干数据类. 以下代码以公开的天气查询api为例: 1.网络请求类 我把常用的网络请求方法都封装好了,你只需要写自己的接口,传递apiName,params等参数就可以. #pragma mark ios请求方式 //ios自带的