您的位置:首页 > 理论基础 > 计算机网络

ios--关于子线程发送网络请求接受不到响应问题

2014-05-24 01:09 549 查看
最近在学IOS开发,正试着写个花瓣网图片批量下载的APP,过程中遇到个问题:我起了一个子线程用来,通过不断的发请求,接受响应来异步下载图片,从而可以边下载,边在主线程中执行其他操作。起初,是直接在主线程中调试代码,图片下载很顺利,链接URL部分代码如下:

    NSURL *boardURL = [NSURL URLWithString:[boardURLString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
    NSURLRequest *request = [NSURLRequest requestWithURL:boardURL];
    NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
 //   NSLog(@"%p--%p", [NSThread mainThread], [NSThread currentThread]);
    [conn start];
后来用NSThread新建了个子线程,把上面的代码放到子线程的方法调用。结果NSURLConnectionDataDelegate代理方法- (void)connection: didReceiveResponse: 等都没有执行,即没有收到响应。注意,并不是网络问题,同样条件下在主线程中是OK的。自己思考了下,应该是服务器返回响应了,但是没能传输到子线程中去,猜想可能是子线程在执行完被调用的方法后没能等待接受到响应就被自动释放掉了,或者是在多线程下,返回的响应需要进行某种识别才能正确传输给对应的线程。感觉第一种猜想可能性较大,问了下度娘,发现可能和NSRunLoop有关,最终实践证明第一种猜想是对的。代码中的解决如下
    NSURL *boardURL = [NSURL URLWithString:[boardURLString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
    NSURLRequest *request = [NSURLRequest requestWithURL:boardURL];
    NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    NSLog(@"%p--%p", [NSThread mainThread], [NSThread currentThread]);
    [conn start];
#warning 这里关于线程的使用点,可以研究下
    //表示当前线程一直接受输入源,不会被释放,如果没有下面的代码,子线程到这里就被释放,不会接受其他输入源,从而不会在子线程中执行NSURLconnectionDataDelegate方法
    while(_doingJob) {
        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
    }
_doingJob是全局变量,子线程完成所需的工作后设置为NO。

原来,子线程方法中执行完[conn start];后方法结束,随即该线程就被释放掉了,这样即便服务器返回了数据,也没有接受源接受数据,当然代理的那些方法也不会执行。加上了下面那个while循环后,就能保证该子线程一直存在,直到完成所需的工作跳出循环为止。关于NSRunLoop的原理,我会整理出篇博客放《IOS学习篇》分类里。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: