objective-c iPhone:如何从 url 获取 UIImage?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1760857/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
iPhone: How to get a UIImage from a url?
提问by philfreo
How do you download an image and turn it into a UIImage?
如何下载图像并将其转换为 UIImage?
回答by philfreo
NSURL *url = [NSURL URLWithString:@"http://example.com/image.jpg"];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *img = [[[UIImage alloc] initWithData:data] autorelease];
However, this isn't asynchronous.
然而,这不是异步的。
回答by Matt Long
You should keep in mind that loading the image data with the sample code you've provided in your own answer will block the main thread until the download has completed. This is a useability no-no. The users of your app will think your app is unresponsive. If you want to download an image, prefer NSURLConnection to download it asynchronously in its own thread.
您应该记住,使用您在自己的答案中提供的示例代码加载图像数据将阻止主线程,直到下载完成。这是一个可用性禁忌。您的应用程序的用户会认为您的应用程序没有响应。如果你想下载一个图像,更喜欢 NSURLConnection 在它自己的线程中异步下载它。
Read the Apple documentation about async downloads with NSURLConnection.
阅读有关使用 NSURLConnection 进行异步下载的 Apple 文档。
When your download completes, you can then instantiate your UIImage from the data object:
下载完成后,您可以从数据对象实例化 UIImage:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
if (requestData)
{
self.image = [[[UIImage alloc] initWithData:requestData] autorelease];
}
}
Where requestDataand imageare instance variables of your containing class, and imageis a retained property. Be sure to release imagein the deallocroutine of the class, e.g. using self.image=nil;.
其中requestData和image是包含类的实例变量,并且image是保留属性。一定要image在dealloc类的例程中释放,例如使用self.image=nil;.
回答by Rivera
It is true that Asynchronous loading is a must, but you can also achieve that with a background call if you just need a simple solution.
确实,异步加载是必须的,但如果您只需要一个简单的解决方案,您也可以通过后台调用来实现。
[self performSelectorInBackground:@selector(loadImage) withObject:nil];
- (void)loadImage
{
NSURL * url = [NSURL URLWithString:@"http://.../....jpg"];
NSData * data = [NSData dataWithContentsOfURL:url];
UIImage * image = [UIImage imageWithData:data];
if (image)
{
// Success use the image
...
}
else
{
// Failed (load an error image?)
...
}
}
回答by superpuccio
You can load an image in a UIImageViewfrom a URL without blocking the UI thread simply using the dispatch_async:
您可以UIImageView从 URL加载图像,而无需阻塞 UI 线程,只需使用dispatch_async:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSURL *url = [NSURL URLWithString:myURL];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage* image = [[UIImage alloc]initWithData:data];
dispatch_async(dispatch_get_main_queue(), ^{
[myImageView setImage:image];
});
});
The first dispatch_asyncis used to load the image from the URL in background (without blocking the UI). The second dispatch_asyncis used to actually inject the image just loaded in the UIImageView. Please, note that the second dispatch_asyncis designed to work on the main thread(the UI thread) that is, indeed, the thread used to update the UI.
第一个dispatch_async用于在后台从 URL 加载图像(不阻塞 UI)。第二个dispatch_async用于实际注入刚刚加载到UIImageView. 请注意,第二个dispatch_async设计用于在主线程(UI 线程)上工作,实际上是用于更新 UI 的线程。
回答by Liam Amster
There is a really good example here using blocks: http://ios-blog.co.uk/iphone-development-tutorials/uiimage-from-url-%E2%80%93-simplified-using-blocks/
这里有一个使用块的很好的例子:http: //ios-blog.co.uk/iphone-development-tutorials/uiimage-from-url-%E2%80%93-simplified-using-blocks/
回答by Besi
Based on @philfreo's answer I created a NSURL Extension in swift using BrightFutures (for the asynchronous callback:
基于@philfreo 的回答,我使用 BrightFutures 快速创建了一个 NSURL 扩展(用于异步回调:
extension NSURL{
func downloadImage() -> Future<UIImage, NSError>{
let promise = Promise<UIImage, NSError>()
Queue.global.async{
if let data = NSData(contentsOfURL: self){
if let image = UIImage(data: data){
promise.success(image)
return
}
}
promise.failure(NSError())
}
return promise.future
}
}
This then lets me do:
这让我可以这样做:
import BrightFutures
let someURL = ...;
someURL.downloadImage().onSuccess{ image in
// Do something with the UIImage
}
Update
更新
A simple synchronous extension could look like this:
一个简单的同步扩展看起来像这样:
extension NSURL{
func downloadImage() -> UIImage?{
if let data = NSData(contentsOfURL: self){
return UIImage(data: data){
}
return nil
}
}


