【问题标题】:Does -dataWithContentsOfURL: of NSData work in a background thread?NSData 的 -dataWithContentsOfURL: 是否在后台线程中工作?
【发布时间】:2010-06-20 09:30:15
【问题描述】:

NSData 的 -dataWithContentsOfURL: 是否在后台线程中工作?

【问题讨论】:

    标签: iphone nsdata


    【解决方案1】:

    不,它没有。

    为了从 URL 异步获取数据,您应该使用 NSURLRequestNSURLConnection 方法。

    您必须实现 NSURLConnectionDelegate 方法:

    -(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;
    -(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;
    -(void)connectionDidFinishLoading:(NSURLConnection *)connection;
    -(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error;
    

    【讨论】:

    • 这篇文章展示了如何在后台线程上使用+dataWithContentsOfURL: 来实现相同结果的示例:londonwebdev.com/2011/01/13/…
    • 当然!任何事情都可以在后台线程中完成,但这不是问题。此外,我会对 NSOperationQueue 做同样的事情,而不是在你提到的帖子中实现它......
    • @user8472,再次阅读问题和答案... dataWithContentsOfURL 方法本身不会在后台执行。显然,您可以(几乎)在后台线程中执行任何操作。您有很多可能性——不仅是我建议的一种(这是dataWithContentsOfURL 的并行解决方案)。您也可以通过performSelectorInBackground...NSOperation + NSOperationQueue、块(正如您所提到的)和其他几种方式来实现它......底线 - 我的回答没有冲突。
    • 看来最初的问题是模棱两可的 - 它可以被解释为以任何一种方式阅读。实际上,我找到了访问此页面的方式,想知道是否可以在后台线程上运行它(我现在已经确认可以)。我从来没有编辑过一个问题——这是我们可以编辑它的那种东西——以澄清歧义吗?这可以帮助将来提出这个问题的人。
    【解决方案2】:

    我在后台线程中使用 dataWithContentsOfURL 很好。

    -(void)loaddata {
        NSData* data = [NSData dataWithContentsOfURL:@"some url"];
        if (data == nil) {
            DLog(@"Could not load data from url: %@", url);
            return;
        }
    }
    

    从主线程调用类似的东西。

    [self performSelectorInBackground:@selector(loaddata) withObject:nil];
    

    如果您想在加载数据结束时对 ui 执行更新,请务必在主线程上调用函数。

    【讨论】:

      【解决方案3】:

      没有。不过,您可以改用 NSURLSession。

      NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
      
      NSString *imageURL = @"Direct link to your download";
      
      NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfig delegate:self delegateQueue:nil];
      
      NSURLSessionDownloadTask *getImageTask = [session downloadTaskWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:imageURL]] completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
          dispatch_async(dispatch_get_main_queue(), ^{
      
              UIImage *downloadedImage = [UIImage imageWithData:[NSData dataWithContentsOfURL:location]];
          });
      }]; 
      [getImageTask resume];
      

      【讨论】:

        【解决方案4】:

        不,它阻塞了当前线程。

        您需要使用NSURLConnection 才能进行异步请求。

        【讨论】:

          【解决方案5】:

          你也可以使用 -dataWithContentsOfURL + NSOperation + NSOperationQueue

          【讨论】:

            【解决方案6】:

            我猜这些年来这已经发生了一些变化。但是,这些天来,

            NSURLRequest* request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:urlString]];
            [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse* response, NSData* data, NSError* error) {
            }];
            

            会给你一个异步网络调用。

            【讨论】:

              【解决方案7】:

              不,这会阻塞线程,您会将文件的内容加载到 RAM 中。您可以将内容直接下载到文件中而无需临时 NSData 以避免大量 RAM 使用。像这样的解决方案https://stackoverflow.com/a/6215458/2937913

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2011-07-14
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2017-11-20
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多