同步AFNetworking请求

来源:互联网 发布:mallat小波分解算法 编辑:程序博客网 时间:2024/04/30 04:51

原文地址:http://xiangwangfeng.com/2014/11/29/NSURLProtocol%E5%92%8CNSRunLoop%E7%9A%84%E9%82%A3%E4%BA%9B%E5%9D%91/

虽然Mattt各种鄙视同步做网络请求,但是我们不可否认某些场景下使用同步调用会带来不少便利。一种比较简单的实现是使用信号量做同步:

@implementation AFHTTPRequestOperation (YX)- (void)yxStartSynchronous{    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);    [self setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {        dispatch_semaphore_signal(semaphore);    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {        dispatch_semaphore_signal(semaphore);    }];    [self start];    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);}@end

但是这样带来的问题是在UI线程调用同步请求就会导致线程堵死崩溃(好吧,就不应该允许UI线程上这么做)。一种改进的方法是使用NSRunLoop

即:

while (_shouldBlock)    {        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode                                 beforeDate:[NSDate distantFuture]];   }

但是这种写法是有大坑的:如果当前NSRunLoop并没有任何NSTimer或Input Source,runMode:beforeDate:方法将立刻返回NO,于是造成死循环,占用大量CPU,进而导致NSURLConnection请求超时。 规避的方法是往RunLoop中添加NSTimer或者空NSPort使得NSRunLoop挂起而不占用CPU。(ASIHttpRequest就是在当前RunLoop中添加了0.25秒触发一次的刷新Timer)

结语:个人建议,既然你的应用工程选用AF作为网络请求的,最好不要去没事搞神马同步请求

0 0