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 异步获取数据,您应该使用 NSURLRequest
和 NSURLConnection
方法。
您必须实现 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 对象而不损坏数据吗?