特点

  • 专门用来在主线程上调度任务的队列
  • 不会开启线程
  • 先进先出的方式,在主线程空闲时才会调度队列中的任务在主线程执行
  • 如果当前主线程正在有任务执行,那么无论主队列中当前被添加了什么任务,都不会被调度

队列获取

  • 主队列是负责在主线程调度任务的
  • 会随着程序启动一起创建
  • 主队列只需要获取不用创建

    异步主队列

  1. - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
  2. [self gcdDemo1];
  3. [NSThread sleepForTimeInterval:1];
  4. NSLog(@"over");
  5. }
  6. - (void)gcdDemo1 {
  7. dispatch_queue_t queue = dispatch_get_main_queue();
  8. for (int i = 0; i < 10; ++i) {
  9. dispatch_async(queue, ^{
  10. NSLog(@"%@ - %d", [NSThread currentThread], i);
  11. });
  12. NSLog(@"---> %d", i);
  13. }
  14. NSLog(@"come here");
  15. }

主线程空闲时才会调度队列中的任务在主线程执行

同步主队列

  1. // MARK: 主队列,同步任务
  2. - (void)gcdDemo6 {
  3. // 1. 队列
  4. dispatch_queue_t q = dispatch_get_main_queue();
  5. NSLog(@"!!!");
  6. // 2. 同步
  7. dispatch_sync(q, ^{
  8. NSLog(@"%@", [NSThread currentThread]);
  9. });
  10. NSLog(@"come here");
  11. }
  1. - (void)viewDidLoad {
  2. [super viewDidLoad];
  3. // 会造成死锁
  4. dispatch_sync(dispatch_get_main_queue(), ^{
  5. NSLog(@"%@", [NSThread currentThread]);
  6. });
  7. }

死锁原因:队列引起的循环等待

image.png

同步串行

  1. - (void)viewDidLoad {
  2. [super viewDidLoad];
  3. dispatch_queue_t serialQueue = dispatch_queue_create("serialQueue", DISPATCH_QUEUE_SERIAL);
  4. // 不会造成死锁
  5. dispatch_sync(serialQueue, ^{
  6. NSLog(@"%@", [NSThread currentThread]);
  7. });
  8. }

image.png

注意:使用sync函数往当前串行队列中添加任务,会卡住当前的串行队列(产生死锁)