使用GCD处理非UI相关的异步任务 Object-C异步多线程加载网络图片

两个核心方法:dispatch_async和dispatch_async_f,分别对应Block Objects方法和C Functions方法。
我们举一个场景来进行:

当我们需要从网络下载一个图片,可以将这个下载工作丢到一个异步线程里面,然后当图片下载完毕后,我们再交给主线程,让主线程去显示这个图片。在这种场景下,我们就需要甬道异步任务了。这里也涉及到了之前提到的__block方式操作本地资源。

代码演示如下:

dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(concurrentQueue, ^{
    __block UIImage *image = nil;
    dispatch_sync(concurrentQueue, ^{ 
        /* Download the image here */
    });
    dispatch_sync(dispatch_get_main_queue(), ^{
        /* Show the image to the user here on the main queue*/
    }); 
}); 

 

 

下面看一个具体的代码实现:

- (void) viewDidAppear:(BOOL)paramAnimated{
    dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(concurrentQueue, ^{ 
        __block UIImage *image = nil;
        dispatch_sync(concurrentQueue, ^{ 
            /* Download the image here */
            /* iPad's image from Apple's website. Wrap it into two lines as the URL is too long to fit into one line */
            NSString *urlAsString = @"http://images.apple.com/mobileme/features"\ "/images/ipad_findyouripad_20100518.jpg";
            NSURL *url = [NSURL URLWithString:urlAsString];
            NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
            NSError *downloadError = nil;
            NSData *imageData = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:nil error:&downloadError];
            if (downloadError == nil && imageData != nil){
                image = [UIImage imageWithData:imageData]; /* We have the image. We can use it now */
            }
            else if (downloadError != nil){
                NSLog(@"Error happened = %@", downloadError); 
            } 
            else 
            {
                NSLog(@"No data could get downloaded from the URL."); 
            }
        });

        dispatch_sync(dispatch_get_main_queue(), ^{
            /* Show the image to the user here on the main queue*/
            if (image != nil){
                /* Create the image view here */
                UIImageView *imageView = [[UIImageView alloc] initWithFrame:self.view.bounds];
                /* Set the image */ 
                [imageView setImage:image];
                /* Make sure the image is not scaled incorrectly */ 
                [imageView setContentMode:UIViewContentModeScaleAspectFit];
                /* Add the image to this view controller's view */ 
                [self.view addSubview:imageView];
            } else {
                NSLog(@"Image isn't downloaded. Nothing to display.");
            } 
        });
    }); 
} 

 

 
posted @ 2012-12-13 15:28  hhhker  阅读(1562)  评论(0编辑  收藏  举报