在iOS中使用线程返回图像 [英] Returning image with threading in iOS
问题描述
您好,我正在学习Stanford iOS开发课程.我有一个关于线程的问题.我了解UIKit调用应由主线程处理.我想知道这样的事情是否合法?
Hi I'm working through the Stanford iOS development class. I have a question regarding threading. I understand UIKit calls should be handled by the main thread. I was wondering if something like this is legal?
- (UIImage *)mapViewController:(MapViewController *)sender imageForAnnotation:(id<MKAnnotation>)annotation {
FlickrPhotoAnnotation *fpa = (FlickrPhotoAnnotation *) annotation;
NSURL *url = [FlickrFetcher urlForPhoto:fpa.photo format:FlickrPhotoFormatSquare];
__block UIImage *image;
dispatch_queue_t downloadQ = dispatch_queue_create("download queue", NULL);
dispatch_async(downloadQ, ^{
NSData *data = [NSData dataWithContentsOfURL:url];
if (data) {
dispatch_async(dispatch_get_main_queue(), ^{
image = [UIImage imageWithData:data];
});
}
});
dispatch_release(downloadQ);
return image;
}
还是我应该只返回NSData并处理调用方法中的所有线程?
or I should just return NSData and handle all the threading in the calling method?
谢谢
推荐答案
您的代码不会执行您想要的操作.
Your code won't do what you want.
您正在将异步块放入队列中,然后立即从方法中返回.您不能保证该块实际上会在返回之前运行-实际上,很有可能它不会运行.
You are putting an asynchronous block into a queue, and then immediately returning from the method. You are not guaranteed that the block will actually run before you return -- in fact, the odds are that it won't.
因此,您将返回image
的当前值.由于您没有初始化它,所以可能是垃圾.调用此方法的任何人都将尝试使用指向图像的垃圾指针,并且(如果幸运的话)崩溃.如果您将其初始化为nil:
So you'll return the current value of image
. Since you didn't initialize it, it's probably garbage. Whoever calls this method will try to use a garbage pointer to an image, and (if you're lucky) crash. If you had initialized it to nil:
__block UIImage *image = nil;
礼貌些.
这里的问题是:您的方法必须返回UIImage
,因此在返回之前,必须等待制作完全构造的UIImage
所花费的时间.在其他线程上执行此操作的好处为零-您仍在等待相同的时间,而切换线程只会增加开销.
The problem here is: your method must return a UIImage
, so you must wait for the time it takes to make a fully constructed UIImage
before you return. There is zero benefit to doing this on some other thread -- you're still waiting the same amount of time, and switching threads just adds overhead.
为了以一种有用的异步方式加载图像,您需要某种方式,通过对委托方法或块的回调,异步地告诉调用者何时图像加载完成.例如,查看Foundation中的NSURLConnection
.它具有一个通过委托进行回调的较旧的方法,以及通过一个块进行回调的一个较新的方法(+sendAsynchronousRequest:queue:completionHandler:
).
In order to load the image in a usefully asynchronous way, you need some way to asynchronously tell the caller when the image is done loading, via a callback to a delegate method or block. For example, look at NSURLConnection
in Foundation. It has an older method that calls back via a delegate, and a newer method (+sendAsynchronousRequest:queue:completionHandler:
) that calls back via a block.
这篇关于在iOS中使用线程返回图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!