6.7 Executing Non-UI Related Tasks Asynchronously with GCD

本文介绍了如何使用GCD(Grand Central Dispatch)在iOS开发中异步执行UI无关任务,包括如何提交block对象和C函数到队列进行异步执行,并通过一个实例展示了从网上下载图片并显示的全过程。通过这种方式,可以在主线程更新UI的同时,执行耗时的操作,提高应用的响应速度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


异步执行UI无关任务

这才是GCD大显神威的地方,我保证,学完这一章节后,在以后的多线程编程中,你将深深爱上GCD

dispatch_async

提交block对象到队列以便异步执行


dispatch_async_f

提交C函数到队列,异步执行


我们来实现一个功能,从网上下载一张图片并显示出来。

代码框架是这样的

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*/

}); 

});


第二个dispatch_sync将在第一个dispatch_sync执行后才执行。


看下详细例子

- (void) viewDidAppear:(BOOL)paramAnimated

{

    NSLog(@"viewDidAppear");

    dispatch_queue_t concurrentQueue =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    dispatch_async(concurrentQueue, ^{

        NSLog(@"dispatch_async");

        __block UIImage *image = nil;

        dispatch_sync(concurrentQueue, ^{

            NSLog(@"dispatch_sync1");

            /* 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://i3.sinaimg.cn/home/2013/0331/U586P30DT20130331093840.png";

            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.");

            }

            NSLog(@"dispatch_sync1 over");

        });

        dispatch_sync(dispatch_get_main_queue(), ^{

            NSLog(@"dispatch_sync2");

            /* 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]; [imageView setImage:image];

                /* Set the 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.");

            }

            

            NSLog(@"dispatch_sync2 over");

        });

        NSLog(@"dispatch_async over");

    });

    NSLog(@"viewDidAppear over");

}


执行结果是

2014-03-05 17:26:56.042 cookbook6_7[699:a0b] viewDidAppear

2014-03-05 17:26:56.043 cookbook6_7[699:a0b] viewDidAppear over

2014-03-05 17:26:56.043 cookbook6_7[699:1403] dispatch_async

2014-03-05 17:26:56.043 cookbook6_7[699:1403] dispatch_sync1

2014-03-05 17:26:56.073 cookbook6_7[699:1403] dispatch_sync1 over

2014-03-05 17:26:56.073 cookbook6_7[699:a0b] dispatch_sync2

2014-03-05 17:26:56.075 cookbook6_7[699:a0b] dispatch_sync2 over

2014-03-05 17:26:56.077 cookbook6_7[699:1403] dispatch_async over


这里还有一个小小例子,

- (void) viewDidAppear:(BOOL)paramAnimated

{

    NSLog(@"viewDidAppear");

    dispatch_queue_t concurrentQuene =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    dispatch_async(concurrentQuene,^{

        NSLog(@"Call1");

        dispatch_sync(concurrentQuene,^{

            [NSThread sleepForTimeInterval:2];

            NSLog(@"Call2");

        });

        dispatch_sync(dispatch_get_main_queue(),^{

            NSLog(@"Call3");  

        });

    });

    

}


由于对这套东西还不是很熟悉,我一直不明白第一个dispatch_sync有什么用,把它去掉结果也都一样,后来在网上有人告诉我说,去掉不影响结果的正确性,加上后可以有多线程的优化而已。不知事实是否如此。












评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值