dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, ), ^{
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:urlStr] cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:CONNECTIONT_TIMEOUT];
NSString *encodedStr = [body stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSData *sendData = [encodedStr dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
NSString *dataLengthStr =[NSString stringWithFormat:@"%lu",(unsigned long)[sendData length]];
[request setValue:dataLengthStr forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
[request setHTTPMethod:@"POST"];
[request setHTTPBody:sendData];
self.connection = [NSURLConnection connectionWithRequest:request delegate:self];
});

这是一个在主线程中执行的代码,执行结果有问题,无法执行网络回调函数。

原因如下:对于connectionWithRequest这个函数在官方文档下有以下说明:

Delegate methods are called on the same thread that called this method.

这就是说,delegate的消息会发送到调用connectionWithRequest方法的线程中去。如果线程结束了,比如这里就是这样,那么,系统就不会调用相应方法,即使delegate对象本身是存在的!

改正方法很简单,有2种

1.把网络请求发送代码放到主线程,就是不使用dispatch_async

2.在dispatch_async 块的结尾处调用

 NSRunLoop *loop = [NSRunLoop currentRunLoop];

 [loop run];

当connection完成回调后,会把自己(source)从runloop中移除,这样这个runloop中就没有任何source和timer了,这个runloop会自动停止,相关线程自动结束。

下面是关于run方法的说明,可见,如果没有input source 和timer 加入nsrunloop,这个run方法会立即返回的(这个经过了测试,也十分重要!)。总结下就是,在一个runloop中还有source时,如果调用了run,那么当runloop的source都没了时,这个run方法会自动返回!

If no input sources or timers are attached to the run loop, this method exits immediately; otherwise, it runs the receiver in the NSDefaultRunLoopMode by repeatedly invoking runMode:beforeDate:. In other words, this method effectively begins an infinite loop that processes data from the run loop’s input sources and timers.

再看看runloop的说明

The NSRunLoop class declares the programmatic interface to objects that manage input sources. An NSRunLoop object processes input for sources such as mouse and keyboard events from the window system, NSPort objects, and NSConnection objects. An NSRunLoop object also processes NSTimer events.

这里说明,nsrunloop主要处理2种消息,一种是input source 一种是timer(注意,nsobject中的performSelector的一系列函数就是利用timer放入到runloop中的),而input source分为4种,分别是鼠标消息,键盘消息,port消息(不太明白),nsconnection (不仅仅是网络连接)消息。

另外还需要注意 You should never try to call the methods of an NSRunLoop object running in a different thread, as doing so might cause unexpected results. 也就是说,不要在其他线程中通过调用 runloop对象让runloop停止!必须放到自己的线程中做,这个错误很容易犯。

这个错误提醒我,在使用dispatch_async时,如果没有特殊操作,相关线程会在block结束后立即退出,仅仅靠系统自动加入的input source(比如这里的nsurlconnection),是无法使线程继续存活的,因为加入input source或timer 后还需要我们启动 runloop才行。除了主线程,系统不会为你自动启动runloop的。

iOS NSURLConnection 和 dispatch_async 错误的使用方法,导致回调方法无法调用的更多相关文章

  1. iOS开发--UIButton 设置圆角 边框颜色 点击回调方法

    UIButton *signBtn = [UIButton buttonWithType:UIButtonTypeCustom]; signBtn.frame = CGRectMake(, , , ) ...

  2. Java回调方法详解

    回调在维基百科中定义为: 在计算机程序设计中,回调函数,是指通过函数参数传递到其他代码的,某一块可执行代码的引用. 其目的是允许底层代码调用在高层定义的子程序. 举个例子可能更明白一些:以Androi ...

  3. java回调方法、钩子方法以及模板方法模式

    在面向对象的语言中,回调则是通过接口或抽象类来实现的,我们把实现这种接口的类称为回调类,回调类的对象称为回调对象,其处理事件的方法叫做回调方法.(摘自百度百科) 那么通过上面那句话将百度百科中的&qu ...

  4. iOS - NSURLConnection 网络请求

    前言 @interface NSURLConnection : NSObject class NSURLConnection : NSObject DEPRECATED: The NSURLConne ...

  5. iOS 真机测试错误“The application bundle does not contain a valid identifier”

    iOS 真机测试错误"The application bundle does not contain a valid identifier" 真机测试的时候报错:"The ...

  6. iOS开发中常见bug!(内附解答方法)

    序言 你是否曾经修复了一个 bug ,随后又发现了一个跟刚修复 bug 有关的 bug ,又或是修复 bug 的方式引起了另一个 bug ? 然而这些问题是绝佳的学习机会.所以我们怎样尽可能多地从修复 ...

  7. iOS NSURLConnection使用详解

    一.整体介绍 NSURLConnection是苹果提供的原生网络访问类,但是苹果很快会将其废弃,且由NSURLSession(iOS7以后)来替代.目前使用最广泛的第三方网络框架AFNetworkin ...

  8. iOS 真机测试错误“The application could not be verified”

    iOS 真机测试错误"The application could not be verified" 真机测试的时候报错:"The application could no ...

  9. iOS之友盟错误统计解决

    http://www.cocoachina.com/ios/20150720/12627.html http://lieyunye.github.io/blog/2013/09/10/how-to-a ...

随机推荐

  1. 【BZOJ 1001】狼抓兔子 对偶图+SPFA

    这道题是求图的最小割,也就是用最大流.但因为边太多,最大流算法会T,因此不能用最大流算法. 因为这是个平面图,所以求平面图的最小割可以使用特殊的技巧就是求对偶图然后求对偶图的最短路.把每个面看成一个点 ...

  2. POJ1201 Intervals

    Description You are given n closed, integer intervals [ai, bi] and n integers c1, ..., cn. Write a p ...

  3. (Beta)Let's-Beta阶段展示博客

    康家华:http://www.cnblogs.com/AmazingMax/ 马阿姨:http://www.cnblogs.com/oushihuahua/ 刘彦熙:http://www.cnblog ...

  4. Vijos1459 车展 (treap)

    描述 遥控车是在是太漂亮了,韵韵的好朋友都想来参观,所以游乐园决定举办m次车展.车库里共有n辆车,从左到右依次编号为1,2,…,n,每辆车都有一个展台.刚开始每个展台都有一个唯一的高度h[i].主管已 ...

  5. HDU1698 Just a Hook

    Description In the game of DotA, Pudge’s meat hook is actually the most horrible thing for most of t ...

  6. Redis Installation、Configuration、Program Based On Redis Learning

    目录 . Redis 简介 . Redis安装配置 . 编程使用Redis . 使用Lua脚本 1. Redis 简介 0x1: Redis是什么 Redis是一款Nosql类型的基于key-valu ...

  7. JS Resizable Panel 练习

    Resizable Panel HTML <!doctype html> <html> <head> <title>Resizable Panel< ...

  8. python学习笔记之module && package

    个人总结: import module,module就是文件名,导入那个python文件 import package,package就是一个文件夹,导入的文件夹下有一个__init__.py的文件, ...

  9. Linux下使用popen()执行shell命令

    转载 http://www.cnblogs.com/caosiyang/archive/2012/06/25/2560976.html 简单说一下popen()函数 函数定义 #include < ...

  10. Canvas与Image互转

    function fImageToCanvas(image){ var oCanvas = document.createElement("canvas"); oCanvas.wi ...