iOS开发多线程篇—GCD的基本使用

本文详细介绍了Grand Central Dispatch (GCD) 在iOS开发中的使用方法,包括主队列的功能与实现方式、如何利用GCD在子线程中加载图片并在主线程中更新UI,以及如何在不同线程间进行通信。

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

一、主队列介绍
主队列:是和主线程相关联的队列,主队列是GCD自带的一种特殊的串行队列,放在主队列中得任务,都会放到主线程中执行。
提示:如果把任务放到主队列中进行处理,那么不论处理函数是异步的还是同步的都不会开启新的线程。
获取主队列的方式:
 dispatch_queue_t queue=dispatch_get_main_queue();
(1)使用异步函数执行主队列中得任务,代码示例:
 1   //
 2   //  YYViewController.m
 3   //  12-GCD的基本使用(主队列)
 4   //
 5   //  Created by 孔医己 on 14-6-25.
 6   //  Copyright (c) 2014年 itcast. All rights reserved.
 7   //
 8  
 9   #import   "YYViewController.h"
10  
11   @interface  YYViewController ()
12  
13   @end
14  
15   @implementation  YYViewController
16  
17  - ( void )viewDidLoad
18  {
19      [super viewDidLoad];
20      
21       //打印主线程
22       NSLog( @"打印主线程--%@" , [NSThread mainThread]);
23      
24       //1.获取主队列
25      dispatch_queue_t queue=dispatch_get_main_queue();
26       //2.把任务添加到主队列中执行
27      dispatch_async(queue, ^{
28          NSLog( @"使用异步函数执行主队列中的任务1--%@" ,[NSThread currentThread]);
29      });
30      dispatch_async(queue, ^{
31          NSLog( @"使用异步函数执行主队列中的任务2--%@" ,[NSThread currentThread]);
32      });
33      dispatch_async(queue, ^{
34          NSLog( @"使用异步函数执行主队列中的任务3--%@" ,[NSThread currentThread]);
35      });
36  }
37  
38   @end
执行效果:
 (2)使用同步函数,在主线程中执行主队列中得任务,会发生死循环,任务无法往下执行。示意图如下:
二、基本使用
1.问题  
任务1和任务2是在主线程执行还是子线程执行,还是单独再开启一个新的线程?
 1   //
 2   //  YYViewController.m
 3   //  13-GCD基本使用(问题)
 4   //
 5   //  Created by 孔医己 on 14-6-25.
 6   //  Copyright (c) 2014年 itcast. All rights reserved.
 7   //
 8  
 9   #import   "YYViewController.h"
10  
11   @interface  YYViewController ()
12  
13   @end
14  
15   @implementation  YYViewController
16  
17  - ( void )viewDidLoad
18  {
19      [super viewDidLoad];
20       //开启一个后台线程,调用执行test方法
21      [self performSelectorInBackground:@selector(test) withObject:nil];
22  }
23  
24  -( void )test
25  {
26      NSLog( @"当前线程---%@" ,[NSThread currentThread]);
27      dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,  0 );
28      
29       //异步函数
30      dispatch_async(queue, ^{
31          NSLog( @"任务1所在的线程----%@" ,[NSThread currentThread]);
32      });
33      
34       //同步函数
35      dispatch_sync(queue, ^{
36          NSLog( @"任务2所在的线程----%@" ,[NSThread currentThread]);
37      });
38  }
39  
40   @end
打印结果:
2.开启子线程,加载图片
 1   //
 2   //  YYViewController.m
 3   //  14-GCD基本使用(下载图片)
 4   //
 5   //  Created by 孔医己 on 14-6-25.
 6   //  Copyright (c) 2014年 itcast. All rights reserved.
 7   //
 8  
 9   #import   "YYViewController.h"
10  
11   @interface  YYViewController ()
12  @property (weak, nonatomic) IBOutlet UIImageView *imageView;
13  
14   @end
15  
16   @implementation  YYViewController
17  
18  - ( void )viewDidLoad
19  {
20      [super viewDidLoad];
21      
22  }
23  
24   //当手指触摸屏幕的时候,从网络上下载一张图片到控制器的view上显示
25  -( void )touchesBegan:(NSSet *)touches withEvent:(UIEvent *) event
26  {
27      
28       //1.获取一个全局串行队列
29      dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,  0 );
30       //2.把任务添加到队列中执行
31      dispatch_async(queue, ^{
32          
33           //打印当前线程
34          NSLog( @"%@" ,[NSThread currentThread]);
35         //3.从网络上下载图片
36          NSURL *urlstr=[NSURL URLWithString: @"http://h.hiphotos.baidu.com/baike/w%3D268/sign=30b3fb747b310a55c424d9f28f444387/1e30e924b899a9018b8d3ab11f950a7b0308f5f9.jpg" ];
37          NSData *data=[NSData dataWithContentsOfURL:urlstr];
38          UIImage *image=[UIImage imageWithData:data];
39           //提示
40          NSLog( @"图片加载完毕" );
41          
42           //4.回到主线程,展示图片
43          [self.imageView performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:NO];
44      });
45  }
46  
47   @end
显示效果:
打印结果:
要求使用GCD的方式,在子线程加载图片完毕后,主线程拿到加载的image刷新UI界面。
 1   //
 2   //  YYViewController.m
 3   //  14-GCD基本使用(下载图片)
 4   //
 5   //  Created by 孔医己 on 14-6-25.
 6   //  Copyright (c) 2014年 itcast. All rights reserved.
 7   //
 8  
 9   #import   "YYViewController.h"
10  
11   @interface  YYViewController ()
12  @property (weak, nonatomic) IBOutlet UIImageView *imageView;
13  
14   @end
15  
16   @implementation  YYViewController
17  
18  - ( void )viewDidLoad
19  {
20      [super viewDidLoad];
21      
22  }
23  
24   //当手指触摸屏幕的时候,从网络上下载一张图片到控制器的view上显示
25  -( void )touchesBegan:(NSSet *)touches withEvent:(UIEvent *) event
26  {
27      
28       //1.获取一个全局串行队列
29      dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,  0 );
30       //2.把任务添加到队列中执行
31      dispatch_async(queue, ^{
32          
33           //打印当前线程
34          NSLog( @"%@" ,[NSThread currentThread]);
35         //3.从网络上下载图片
36          NSURL *urlstr=[NSURL URLWithString: @"http://h.hiphotos.baidu.com/baike/w%3D268/sign=30b3fb747b310a55c424d9f28f444387/1e30e924b899a9018b8d3ab11f950a7b0308f5f9.jpg" ];
37          NSData *data=[NSData dataWithContentsOfURL:urlstr];
38          UIImage *image=[UIImage imageWithData:data];
39           //提示
40          NSLog( @"图片加载完毕" );
41          
42           //4.回到主线程,展示图片
43   //        [self.imageView performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:NO];
44          dispatch_async(dispatch_get_main_queue(), ^{
45              self.imageView.image=image;
46               //打印当前线程
47              NSLog( @"%@" ,[NSThread currentThread]);
48          });
49      });
50  }
51  
52   @end
打印结果:
好处:子线程中得所有数据都可以直接拿到主线程中使用,更加的方便和直观。
 
三、线程间通信
从子线程回到主线程
dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,  0 ), ^{
// 执⾏耗时的异步操作...
dispatch_async(dispatch_get_main_queue(), ^{

// 回到主线程,执⾏UI刷新操作
});
});  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值