如何使用块异步下载图像?

时间:2013-02-13 19:20:50

标签: objective-c ios6 objective-c-blocks

我想点击一个按钮开始下载图像,并在更新后将我的UIImageView更新为新图像。我的代码的问题是它只下载东西,而不是更新。它只会在我再次单击它时更新。 我想让它在将来的某个时候更新图像,下载图像时。我该怎么做?

编辑:我发现错误的代码,改变它有点帮助,一切正常。 接下来是另一个问题 - 如何简化这些代码而不会弄乱它?看起来太过分了。

- (IBAction)getImage
{

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
     ^{
        NSURL *imageURL = [NSURL URLWithString:@"http://example.com/1.jpg"];
        __block NSData *imageData;

         dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
            ^{
                imageData = [NSData dataWithContentsOfURL:imageURL];


                dispatch_sync(dispatch_get_main_queue(), ^{
                                             self.image = [UIImage imageWithData:imageData];
                                         });
                                     });


     });

    self.imageView.image = self.image;
}

3 个答案:

答案 0 :(得分:21)

在下载图像之前设置imageView,需要将逻辑移动到块中。此外,您没有理由在dispatch_sync内额外dispatch_async

- (IBAction)getImage
{

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
     ^{
        NSURL *imageURL = [NSURL URLWithString:@"http://example.com/1.jpg"];
        NSData *imageData = [NSData dataWithContentsOfURL:imageURL];

        //This is your completion handler
        dispatch_sync(dispatch_get_main_queue(), ^{
             //If self.image is atomic (not declared with nonatomic)
             // you could have set it directly above
             self.image = [UIImage imageWithData:imageData];

             //This needs to be set here now that the image is downloaded
             // and you are back on the main thread
             self.imageView.image = self.image;

         });
     });

     //Any code placed outside of the block will likely
     // be executed before the block finishes.
}

答案 1 :(得分:2)

查看https://github.com/rs/SDWebImage

我使用它在后台下载图像并附带进度通知。可以使用Cocoapods(http://cocoapods.org)将其添加到您的项目中。

Cocoapods和GitHub上还有其他一些异步图像加载器,如果这对您不起作用的话。

答案 2 :(得分:0)

这是我一直在使用的,虽然它没有提供我认为通常有用的任何进展。这很简单。

- (void)downloadImageWithURL:(NSURL *)url completionBlock:(void (^)(BOOL succeeded, NSData *image))completionBlock
{
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

    [NSURLConnection sendAsynchronousRequest:request
                                       queue:[NSOperationQueue mainQueue]
                           completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
                               if ( !error )
                               {
                                   completionBlock(YES,data);
                                   NSLog(@"downloaded FULL size %lu",(unsigned long)data.length);
                               } else{
                                   completionBlock(NO,nil);
                               }
                           }];
}