1

我正在从 Web 服务添加图像。我将如何对其进行编码以使其不在主线程上?我希望先加载视图,然后加载图像,以便用户在加载详细视图控制器时不会遇到任何缓慢。

我不确定如何将其添加到调度代码中。

到目前为止,这是我的代码:

   NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:mainImageUrl]];
UIImage *image = [[UIImage alloc] initWithData:imageData];

UIView *v = [[UIView alloc] initWithFrame:CGRectMake(10, 150, 300, 180)];
UIImageView *iv = [[UIImageView alloc] initWithFrame:CGRectMake(0, 10, 300, 180)];
[iv setImage:image];

[_scrollView addSubview:v];
[v addSubview:iv];

这就是我认为我可以用于线程的内容:

dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Add code here to do background processing
//
//
dispatch_async( dispatch_get_main_queue(), ^{
    // Add code here to update the UI/send notifications based on the
    // results of the background processing
});

});

谢谢您的帮助

4

7 回答 7

2

您可以像这样使用 GCD 下载图像。

//Your ImageView
UIImageView *iv = [[UIImageView alloc] initWithFrame:CGRectMake(0, 10, 300, 180)];
// Create a __block type reference for the variable, for ARC use __weak instead
__block UIImageView *blockimage = iv;

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH,  0ul);
dispatch_async(queue, ^{
    NSData *imageData=[NSData dataWithContentsOfURL:[NSURL URLWithString:mainImageUrl]];
    dispatch_sync(dispatch_get_main_queue(), ^{
        blockimage.image = [UIImage imageWithData:imageData];
        // To avoid retain cycle
        blockimage = nil;
    });
});

此代码使用dataWithContentsOfURL:API 在 GCD 异步块内同步下载图像,缺点是当图像下载失败时您无法获得准确的信息。在这种情况下要正确处理错误情况,请使用NSURLConnection异步下载图像数据。

此外,正如在您的问题的几个答案中正确建议的那样,您可以使用SDWebImageAFNetworking图像视图类别。这将为您提供图像缓存设施并确保异步下载图像而不会影响主线程性能。

希望有帮助!

于 2013-08-07T09:35:23.757 回答
1

使用SDWebImage在辅助线程上下载图像。它将在辅助线程的 UIImageView 中加载图像。导入 SDWebImage 包并使用此代码

这是代码

#import "SDWebImage/UIImageView+WebCache.h"

[yourimageView setImageWithURL:[NSURL URLWithString:@"your image Url"] placeholderImage:[UIImage imageNamed:@""]];
于 2013-08-07T09:26:59.203 回答
1
 NSURLRequest *req = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://www.hdwallpapersbest.com/wp-content/uploads/2012/12/Beauty-of-Nature-Awesome-Images-01-21.jpg"]];
    [NSURLConnection sendAsynchronousRequest:req queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *res, NSData *data, NSError *err) {

        [_imageView setImage:[UIImage imageWithData:data]];

    }];
于 2013-08-07T09:29:28.857 回答
1

或者你可以使用 UIImageView 上的AFNetworking类别来做到这一点!

于 2013-08-07T09:23:59.993 回答
0

我会按照建议运行代码,dispatch_async将变量设置为使用后台线程。然后用于[self performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:NO];更新主线程上的 UI

于 2013-08-07T09:28:22.603 回答
0

创建 NSOperationQueue 并创建 NSOperation。您必须使用 NSOperation 发出 nsmutableurl 请求。它将在后台开始图像下载。工作完成后,您必须使用主线程上的 performselector 移动到主线程。

[super viewDidLoad];
    // Create a new NSOperationQueue instance.
    NSPerationQueue *operationQueue = [NSOperationQueue new];
    // Create a new NSOperation object using the NSInvocationOperation subclass.
    // Tell it to run the counterTask method.
    NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self
                                                                selector:@selector(counterTask)
                                                                object:nil];
    // Add the operation to the queue and let it to be executed.
    [operationQueue addOperation:operation];
    [operation release];
    // The same story as above, just tell here to execute the colorRotatorTask method.
    NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self
                                                    selector:@selector(colorRotatorTask)
                                                    object:nil];
    [operationQueue addOperation:operation];
    [operation release];
于 2013-08-07T09:23:42.597 回答
0

您提出的代码看起来像是使用 GCD 的正确方法。但是,在这种特定情况下(因为您正在加载 URL),我建议您查看一下NSURLRequestNSURLConnection因为这些类为您完成了它并为设置缓存策略、处理错误等提供了一个很好的框架。

这是一些示例代码:

NSURLRequest* request = [NSURLRequest requestWithURL:yourNSURLObject];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse* response, NSData* data, NSError* error)
{
    // The data is now available in the 'data' object.
    UIImage* image = [UIImage imageWithData:data];
    // Do whatever with the image.
}];
于 2013-08-07T09:33:06.590 回答