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

Posted

技术标签:

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

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

【问题讨论】:

【参考方案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://***.com/a/6215458/2937913

【讨论】:

以上是关于NSData 的 -dataWithContentsOfURL: 是不是在后台线程中工作?的主要内容,如果未能解决你的问题,请参考以下文章

我可以在另一个 NSData 中存档 NSData 对象而不损坏数据吗?

获取 mp3 作为 NSData

从文件中获取 NSData

如何连接 3 个 NSData 变量

将字符串转换为 NSData 并将 NSData 转换回字符串

将 NSObject 转换为 NSData