【发布时间】:2010-06-20 09:30:15
【问题描述】:
NSData 的 -dataWithContentsOfURL: 是否在后台线程中工作?
【问题讨论】:
NSData 的 -dataWithContentsOfURL: 是否在后台线程中工作?
【问题讨论】:
不,它没有。
为了从 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/…
dataWithContentsOfURL 方法本身不会在后台执行。显然,您可以(几乎)在后台线程中执行任何操作。您有很多可能性——不仅是我建议的一种(这是dataWithContentsOfURL 的并行解决方案)。您也可以通过performSelectorInBackground...、NSOperation + NSOperationQueue、块(正如您所提到的)和其他几种方式来实现它......底线 - 我的回答没有冲突。
我在后台线程中使用 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 执行更新,请务必在主线程上调用函数。
【讨论】:
没有。不过,您可以改用 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];
【讨论】:
不,它阻塞了当前线程。
您需要使用NSURLConnection 才能进行异步请求。
【讨论】:
你也可以使用 -dataWithContentsOfURL + NSOperation + NSOperationQueue
【讨论】:
我猜这些年来这已经发生了一些变化。但是,这些天来,
NSURLRequest* request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:urlString]];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse* response, NSData* data, NSError* error) {
}];
会给你一个异步网络调用。
【讨论】:
不,这会阻塞线程,您会将文件的内容加载到 RAM 中。您可以将内容直接下载到文件中而无需临时 NSData 以避免大量 RAM 使用。像这样的解决方案https://stackoverflow.com/a/6215458/2937913
【讨论】: