NSURLConnection 的神奇之处

1.   NSURLConnection一般在主线程中创建初始化 然后start,便能在其回调函数中接收网络数据了,系统貌似也建议不要在子线程中做这样的操作。
     如果NSURLConnection是在主线程中启动的,实际上它就在主线程中运行 -- 并非启动的另外的线程,但又具备异步运行的特性,这个确实是run loop的巧妙所在,估计就是将底层请求在主线程空闲的时候再请求调用的,线程的runLoop对象其实就是一个消息循环,不断的接收和处理消息,NSURLConnection所实现的异步性就是利用了空闲执行这样的特点,所以感觉就好像不会卡主线程(卡界面)一样。但是在子线程中,默认是没有启动runLoop的,所以NSURLConnection的那段代码执行完,这个子线程也就跟着没了,所以回调函数无法执行。

2.  

NSURLConnection 在网络请求的时候(无论主线程还是子线程),如果有点击或滑动界面,网络请求会被暂停执行,直到滑动等操作结束。这是因为 NSURLConnection 默认是 NSDefaultRunLoopMode,也就是说只会在该模式下执行,当有滑动、点击界面等操作的时候,runloop 会切换到 NSEventTrackingRunLoopMode 来处理界面操作,这时候网络请求就会被暂停执行,直到界面操作结束,runloop 模式切换回去。

解决方法就是设置 NSURLConnection 的执行模式为 NSRunLoopCommonModes,这样就会在所有模式下持续执行:

[connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];

3. 另外测试发现,在子线程中进行
NSURLConnection请求,其回调函数理论上也应该是在子线程中执行的,log打出来当前的线程也是子线程对象,但是却可以直接更新主线程UI,哎 奇怪啊???????

4.NSURLConnection  本身支持通信过程中对通信的验证、请求头、请求过程(进度)【这些可用回调函数实现】和最终的数据【如果只关心最终请求到的数据,可通过同步接口+ (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error】, 如果及关心过程(进度等)又关心最终的数据,则需要实现回调系列函数,并在进度回调函数中保存每次请求到的data到其他变量中,待最终请求完成将合并的请求数据给用户

原文地址:https://www.cnblogs.com/cnsec/p/11515802.html