NSURLConnection,NSOperation和NSRunLoop对线程的混淆 [英] NSURLConnection, NSOperation and NSRunLoop confusion over threading

查看:85
本文介绍了NSURLConnection,NSOperation和NSRunLoop对线程的混淆的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在使用NSURLConnection和NSRunLoop时,我感到困惑. 我正在尝试使用NSURLConnection下载大文件,但是按预期无法正常工作(甚至没有调用单个委托方法).

I got confused while working with NSURLConnection and NSRunLoop. I’m trying to download a large file using NSURLConnection but it’s NOT working (Not even calling a single delegate method) as expected.

    NSURL *url = [NSURL URLWithString:@"http://127.0.0.1:8080/"];
    NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] initWithURL:url] autorelease];
    [request setHTTPBody:[@"Request Body Data" dataUsingEncoding:NSUTF8StringEncoding]];
    [request setHTTPMethod:@"POST"];

在主线程上运行.

仅适用于小文件.当我尝试下载18MB的文件时,此方法不起作用.

Only working for small size of file. It didn’t work when I try to download an 18MB file.

  1. 它不适用于大图像文件.

  1. It didn't work for large image files.

[NSURLConnection connectionWithRequest:request delegate:self];

  • 它不适用于较大的图像文件,尝试使用18MB.

  • It didn't work for large image file, tried with 18MB.

    NSURLConnection *con = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
    [con setDelegateQueue:[NSOperationQueue currentQueue]];
    [con start];
    

  • 它不适用于较大的图像文件,尝试使用18MB.

  • It didn't work for large image file, tried with 18MB.

    NSURLConnection *con = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
    [con scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; // Or NSRunLoopCommonModes
    [con start];
    

  • 它不适用于较大的图像文件,尝试使用18MB.

  • It didn't work for large image file, tried with 18MB.

    NSURLConnection *con = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
    NSRunLoop *loop = [NSRunLoop currentRunLoop];
    [con scheduleInRunLoop:loop forMode:NSRunLoopCommonModes];
    [con start];
    [loop run];
    

  • 它不适用于较大的图像文件,尝试使用18MB.

  • It didn't work for large image file, tried with 18MB.

    NSHTTPURLResponse *res = nil;
    NSError *err = nil;
    NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&res error:&err];
    NSLog(@"Res Code: %d, DataLen: %d", res.statusCode, data.length);
    

  • 它也适用于大图像

  • It WORKED for large image as well

    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue currentQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
        NSHTTPURLResponse *res = (NSHTTPURLResponse*)response;
        NSString *imagePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:@"/myImage.jpg"];
        NSLog(@"Res Code: %d, DataLen: %d, Path: %@", res.statusCode, data.length, imagePath);
        [data writeToFile:imagePath atomically:YES];
    }];
    

  • 在NSOperation上运行(我在 NSOperation的子类中尝试了与上述代码相同的代码,我已在github上上传了代码.请在下面找到链接.)

    Running on NSOperation (I have attempted same above code in NSOperation's subclass, I have uploaded the code on github. Please find the link below.)

    1. 什么都没做(没有调用任何委托方法.)
    2. 对所有人都有效.
    3. 它不适用于大文件.
    4. 适用于所有人. (它也适用于NSDefaultRunLoopMode模式,其中Apple文档将其称为用于处理NSConnection对象以外的输入源的模式.").
    5. 对所有人都有效.
    6. 对所有人都有效.

    I just want to understand the basic logic behind NSRunLoop, when we use it with NSURLConnection object. How NSRunLoop works behind the scene? How does it work with NSURLConnections? What happens when we call any asynchronous request through NSURLConnection on main thread or any secondary thread (created by NSOperation)?

    I just want to understand the basic logic behind NSRunLoop, when we use it with NSURLConnection object. How NSRunLoop works behind the scene? How does it work with NSURLConnections? What happens when we call any asynchronous request through NSURLConnection on main thread or any secondary thread (created by NSOperation)?

    GitHub上的示例代码

    Sample Code on GitHub

    我已经阅读了与NSRunLoop相关的多个博客和Apple文档,但仍然感到困惑,因此我就我对NSRunLoop的理解写了一篇文档. NSRunLoop了解文档.

    I have read several blogs and apple documents related to NSRunLoop but still confused, so i have written a doc over my understanding about the same. NSRunLoop understanding Doc.

    非常感谢!

    推荐答案

    混乱很好,这表明您缺少答案甚至可能是问题.据我所知,这里缺少的问题是:我们真的需要NSOperation和NSRunLoop吗? NSURLConnection sendAsynchronousRequest:和sendSynchronousRequest:已经在运行循环中安排了操作-添加NSOperation和NSRunLoop并没有帮助,而且可能会造成阻碍. 因此,专注于您真正需要的方法(sendAsynchronousRequest:或sendSynchronousRequest :)并充分利用它们.输入以下代码:

    Confusion is good, it's a signal that you are missing answers and probably even questions. As far as I can see, the missing question here is: do we really need NSOperation and NSRunLoop? NSURLConnection sendAsynchronousRequest: and sendSynchronousRequest: already schedule operations in runloops -- adding NSOperation and NSRunLoop doesn't help and probably hinders. So, concentrate on the methods that you really need (sendAsynchronousRequest: or sendSynchronousRequest:) and make full use of them. Take this code:

    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue currentQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
        NSHTTPURLResponse *res = (NSHTTPURLResponse*)response;
        NSString *imagePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:@"/myImage.jpg"];
        NSLog(@"Res Code: %d, DataLen: %d, Path: %@", res.statusCode, data.length, imagePath);
        [data writeToFile:imagePath atomically:YES];
    }];
    

    您确实将NSURLResponse强制转换为NSHTTPURLResponse,大概是为了读出状态码,但是相反,您还是先行一步,将数据对象写入文件.如果状态码不是200,则没有有效的数据对象可写入文件.状态码可能为206,在这种情况下,您需要将传入的数据附加到已经存在的文件中,或者如果不存在则创建一个并存储对其的引用,等等.

    You do cast NSURLResponse to NSHTTPURLResponse, presumably to read out the status code, but instead you forge ahead and write the data object to file anyway. If the status code is anything but 200, there is no valid data object to write to file. The status code may be 206, in which case you will need to append the incoming data to an already existing file, or create one if it doesn't exist and store a reference to it, etc.

    这篇关于NSURLConnection,NSOperation和NSRunLoop对线程的混淆的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆