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运行时间划分成若干个时间段,再将时间 段分配 ...
随机推荐
- Java基础-final和static的区别
很多时候会容易把static和final关键字混淆,static作用于成员变量用来表示只保存一份副本,而final的作用是用来保证变量不可变.看下面这个例子: public class Test { ...
- url的编码问题
JQuery中 编码 var url = 'folder/index.html?param=#23dd&noob=yes'; var encodedUrl = encodeURICompone ...
- BIEE 配置邮箱服务器
找个免费邮件服务器126或者163的 登录em地址,点击“部署”——>“邮件”——>“锁定并编辑”——>应用——>激活更改——>重新启动以应用最近更改——>重新启动 ...
- POJ2286 The Rotation Game
Description The rotation game uses a # shaped board, which can hold 24 pieces of square blocks (see ...
- 洛谷P1736 创意吃鱼法
题目描述 回到家中的猫猫把三桶鱼全部转移到了她那长方形大池子中,然后开始思考:到底要以何种方法吃鱼呢(猫猫就是这么可爱,吃鱼也要想好吃法 ^_*).她发现,把大池子视为01矩阵(0表示对应位置无鱼,1 ...
- 【基础语法】a++与++a的区别
package com.on.learn.e2; /** * @author lj * 自增:a++与++a a++是指本行表达式不使用a自增后的值,++a是指本行开始就已经使用a自增后的值 * */ ...
- 轻量级应用开发之(04)UIScrollView-1
本文是我在学习OC中的一些经验总结,在学习中总结了常用的Mac技巧,欢迎群友对本文提出意见,如有问题请联系我. 一 什么是UIScrollView 1)移动设备的屏幕大小是极其有限的,因此直接展示在用 ...
- 栈的的链式实例LinkStack实现
1.#include <stdio.h>#include <malloc.h>#include "LinkList.h"typedef struct _ta ...
- Oracle 11g ORA-00845: MEMORY_TARGET not supported on this system
启动Oracle 11gR2后报错:ORA-00845 rac1:/home/oracle> sqlplus / as sysdba; SQL*Plus: Release 11.2.0.3.0 ...
- configure: error: Please reinstall the libcurl distribution
configure: error: Please reinstall the libcurl distribution - easy.h should be in /include/curl/ 基本上 ...