gcd 实际例子编写

#import "ViewController.h"

 

@interface ViewController ()

@property (weak, nonatomic) IBOutlet UILabel *taskOne;

@property (weak, nonatomic) IBOutlet UILabel *taskTwo;

@property (weak, nonatomic) IBOutlet UILabel *taskThree;

@property (nonatomic, readwrite) int taskOneIndex;

@property (nonatomic, readwrite) int taskTwoIndex;

@property (nonatomic, readwrite) int taskThreeIndex;

@property (nonatomic, strong)  NSTimer *TimerOne;

@property (nonatomic, strong)  NSTimer *TimerTwo;

@property (nonatomic, strong)  NSTimer *TimerThree;

@property (nonatomic, strong) dispatch_queue_t queue1;

 

 

 

@end

 

@implementation ViewController

 

- (void)viewDidLoad {

    [super viewDidLoad];

}

 

- (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

 

- (IBAction)asyncConcurrent:(id)sender {

    //    解释

    //    异步执行意味着

    //    可以开启新的线程

    //    任务可以先绕过不执行,回头再来执行

    //    并行队列意味着

    //    任务之间不需要排队,且具有同时被执行的“权利”

    //    两者组合后的结果

    //    开了三个新线程

    //    函数在执行时,先打印了start和end,再回头执行这三个任务

    //    这三个任务是同时执行的,没有先后

    

    //create a concurrent queue 并行队列意味着不需要排队,具有同时被执行的“权利”

    _queue1 = dispatch_queue_create("ASYNC_CONCURRENT", DISPATCH_QUEUE_CONCURRENT);

    

    NSLog(@"---- start ----");

    //dispatch_async 异步意味着可以开启新的线程,任务可以先绕过不执行,回头再来执行,所以实际长开了新的线程,可以通过打印线程信息得知

    dispatch_async(_queue1, ^{

        NSLog(@"任务1 --- %@", [NSThread currentThread]);

        NSLog(@" -- current thread if on main thread --- %d", [[NSThread currentThread] isEqual:[NSThread mainThread]]);

        dispatch_queue_t mainQueue = dispatch_get_main_queue();

        dispatch_async(mainQueue,^{

            NSLog(@" -- current thread if on main thread after switch --- %d", [[NSThread currentThread] isEqual:[NSThread mainThread]]);

            _TimerOne = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateUI) userInfo:nil repeats:YES];

        });

    });

    

    dispatch_async(_queue1, ^{

        NSLog(@"任务2 --- %@", [NSThread currentThread]);

        NSLog(@" -- current thread if on main thread --- %d", [[NSThread currentThread] isEqual:[NSThread mainThread]]);

        dispatch_queue_t mainQueue = dispatch_get_main_queue();

        dispatch_async(mainQueue,^{

            NSLog(@" -- current thread if on main thread after switch --- %d", [[NSThread currentThread] isEqual:[NSThread mainThread]]);

            _TimerTwo = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateTask2) userInfo:nil repeats:YES];

        });

    });

    

    dispatch_async(_queue1, ^{

        NSLog(@"任务3 --- %@", [NSThread currentThread]);

        NSLog(@" -- current thread if on main thread --- %d", [[NSThread currentThread] isEqual:[NSThread mainThread]]);

        dispatch_queue_t mainQueue = dispatch_get_main_queue();

        dispatch_async(mainQueue,^{

            NSLog(@" -- current thread if on main thread after switch --- %d", [[NSThread currentThread] isEqual:[NSThread mainThread]]);

            _TimerThree = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateTask3) userInfo:nil repeats:YES];

        });

    });

    

    NSLog(@"---- end ----");

}

 

- (IBAction)asyncSerial:(id)sender {

    //    解释

    //    异步执行意味着

    //    可以开启新的线程

    //    任务可以先绕过不执行,回头再来执行

    //    串行队列意味着

    //    任务必须按添加进队列的顺序挨个执行

    //    两者组合后的结果

    //    开了一个新的子线程

    //    函数在执行时,先打印了start和end,再回头执行这三个任务

    //    这三个任务是按顺序执行的,所以打印结果是“任务1-->任务2-->任务3”

    

    //串行意味着任务必须按添加进队列的顺序挨个执行

    dispatch_queue_t queue = dispatch_queue_create("SYNC_CONCURRENT", DISPATCH_QUEUE_SERIAL);

    NSLog(@"---- start ----");

    dispatch_async(queue, ^{

        //一样开启了新的线程

        NSLog(@"任务1 --- %@", [NSThread currentThread]);

        NSLog(@" -- current thread if on main thread --- %d", [[NSThread currentThread] isEqual:[NSThread mainThread]]);

        dispatch_queue_t mainQueue = dispatch_get_main_queue();

        dispatch_async(mainQueue,^{

            NSLog(@" -- current thread if on main thread after switch --- %d", [[NSThread currentThread] isEqual:[NSThread mainThread]]);

            _TimerOne = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateUI) userInfo:nil repeats:YES];

        });

    });

    

    dispatch_async(queue, ^{

        NSLog(@"任务2 --- %@", [NSThread currentThread]);

        NSLog(@" -- current thread if on main thread --- %d", [[NSThread currentThread] isEqual:[NSThread mainThread]]);

        dispatch_queue_t mainQueue = dispatch_get_main_queue();

        dispatch_async(mainQueue,^{

            NSLog(@" -- current thread if on main thread after switch --- %d", [[NSThread currentThread] isEqual:[NSThread mainThread]]);

            _TimerTwo = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateTask2) userInfo:nil repeats:YES];

        });

    });

    

    dispatch_async(queue, ^{

        NSLog(@"任务3 --- %@", [NSThread currentThread]);

        NSLog(@" -- current thread if on main thread --- %d", [[NSThread currentThread] isEqual:[NSThread mainThread]]);

        dispatch_queue_t mainQueue = dispatch_get_main_queue();

        dispatch_async(mainQueue,^{

            NSLog(@" -- current thread if on main thread after switch --- %d", [[NSThread currentThread] isEqual:[NSThread mainThread]]);

            _TimerThree = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateTask3) userInfo:nil repeats:YES];

        });

    });

    NSLog(@"---- end ----");

}

 

- (IBAction)syncConcurrent:(id)sender {

    //    解释

    //    同步执行执行意味着

    //    不能开启新的线程

    //    任务创建后必须执行完才能往下走

    //    并行队列意味着

    //    任务必须按添加进队列的顺序挨个执行

    //    两者组合后的结果

    //    所有任务都只能在主线程中执行

    //    函数在执行时,必须按照代码的书写顺序一行一行地执行完才能继续

    //    注意事项

    //    在这里即便是并行队列,任务可以同时执行,但是由于只存在一个主线程,所以没法把任务分发到不同的线程去同步处理,其结果就是只能在主线程里按顺序挨个挨个执行了

    //create a concurrent queue 并行队列意味着不需要排队,具有同时被执行的“权利”

    _queue1 = dispatch_queue_create("ASYNC_CONCURRENT", DISPATCH_QUEUE_CONCURRENT);

    

    NSLog(@"---- start ----");

    //同步不会创建新的线程,因此需要本次任务结束后再执行下面的任务

    dispatch_sync(_queue1, ^{

        NSLog(@"任务1 --- %@", [NSThread currentThread]);

        NSLog(@" -- current thread if on main thread --- %d", [[NSThread currentThread] isEqual:[NSThread mainThread]]);

        _TimerOne = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateUI) userInfo:nil repeats:YES];

    });

    

    dispatch_sync(_queue1, ^{

        NSLog(@"任务2 --- %@", [NSThread currentThread]);

        NSLog(@" -- current thread if on main thread --- %d", [[NSThread currentThread] isEqual:[NSThread mainThread]]);

        _TimerTwo = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateTask2) userInfo:nil repeats:YES];

    });

    

    dispatch_sync(_queue1, ^{

        NSLog(@"任务3 --- %@", [NSThread currentThread]);

        NSLog(@" -- current thread if on main thread --- %d", [[NSThread currentThread] isEqual:[NSThread mainThread]]);

        _TimerThree = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateTask3) userInfo:nil repeats:YES];

    });

    

    NSLog(@"---- end ----");

}

 

- (IBAction)syncSerial:(id)sender {

//    解释

//    这里的执行原理和步骤图跟“同步执行+并发队列”是一样的,只要是同步执行就没法开启新的线程,所以多个任务之间也一样只能按顺序来执行,

    //create a concurrent queue 并行队列意味着不需要排队,具有同时被执行的“权利”

    _queue1 = dispatch_queue_create("ASYNC_CONCURRENT", DISPATCH_QUEUE_SERIAL);

    

    NSLog(@"---- start ----");

    //同步不会创建新的线程,因此需要本次任务结束后再执行下面的任务

    dispatch_sync(_queue1, ^{

        NSLog(@"任务1 --- %@", [NSThread currentThread]);

        NSLog(@" -- current thread if on main thread --- %d", [[NSThread currentThread] isEqual:[NSThread mainThread]]);

        _TimerOne = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateUI) userInfo:nil repeats:YES];

    });

    

    dispatch_sync(_queue1, ^{

        NSLog(@"任务2 --- %@", [NSThread currentThread]);

        NSLog(@" -- current thread if on main thread --- %d", [[NSThread currentThread] isEqual:[NSThread mainThread]]);

        _TimerTwo = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateTask2) userInfo:nil repeats:YES];

    });

    

    dispatch_sync(_queue1, ^{

        NSLog(@"任务3 --- %@", [NSThread currentThread]);

        NSLog(@" -- current thread if on main thread --- %d", [[NSThread currentThread] isEqual:[NSThread mainThread]]);

        _TimerThree = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateTask3) userInfo:nil repeats:YES];

    });

    

    NSLog(@"---- end ----");

}

 

- (IBAction)asyncMain:(id)sender {

//    解释

//    异步执行意味着

//    可以开启新的线程

//    任务可以先绕过不执行,回头再来执行

//    主队列跟串行队列的区别

//    队列中的任务一样要按顺序执行

//    主队列中的任务必须在主线程中执行,不允许在子线程中执行

//    以上条件组合后得出结果:

//    所有任务都可以先跳过,之后再来“按顺序”执行

    _queue1 = dispatch_get_main_queue();

    NSLog(@"---- start ----");

    dispatch_async(_queue1, ^{

        NSLog(@"任务1 --- %@", [NSThread currentThread]);

        NSLog(@" -- current thread if on main thread --- %d", [[NSThread currentThread] isEqual:[NSThread mainThread]]);

        _TimerOne = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateUI) userInfo:nil repeats:YES];

    });

    

    dispatch_async(_queue1, ^{

        NSLog(@"任务2 --- %@", [NSThread currentThread]);

        NSLog(@" -- current thread if on main thread --- %d", [[NSThread currentThread] isEqual:[NSThread mainThread]]);

        _TimerTwo = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateTask2) userInfo:nil repeats:YES];

    });

    

    dispatch_async(_queue1, ^{

        NSLog(@"任务3 --- %@", [NSThread currentThread]);

        NSLog(@" -- current thread if on main thread --- %d", [[NSThread currentThread] isEqual:[NSThread mainThread]]);

        _TimerThree = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateTask3) userInfo:nil repeats:YES];

    });

    NSLog(@"---- end ----");

}

 

- (IBAction)syncMain:(id)sender {

    _queue1 = dispatch_get_main_queue();

    NSLog(@"---- start ----");

    //同步不会创建新的线程,因此需要本次任务结束后再执行下面的任务,

    //    主队列中的任务必须按顺序挨个执行

    //    任务1要等主线程有空的时候(即主队列中的所有任务执行完)才能执行

    //    主线程要执行完“打印end”的任务后才有空

    //    “任务1”和“打印end”两个任务互相等待,造成死锁

    dispatch_sync(_queue1, ^{

        NSLog(@"任务1 --- %@", [NSThread currentThread]);

        NSLog(@" -- current thread if on main thread --- %d", [[NSThread currentThread] isEqual:[NSThread mainThread]]);

        _TimerOne = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateUI) userInfo:nil repeats:YES];

    });

    

    dispatch_sync(_queue1, ^{

        NSLog(@"任务2 --- %@", [NSThread currentThread]);

        NSLog(@" -- current thread if on main thread --- %d", [[NSThread currentThread] isEqual:[NSThread mainThread]]);

        _TimerTwo = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateTask2) userInfo:nil repeats:YES];

    });

    

    dispatch_sync(_queue1, ^{

        NSLog(@"任务3 --- %@", [NSThread currentThread]);

        NSLog(@" -- current thread if on main thread --- %d", [[NSThread currentThread] isEqual:[NSThread mainThread]]);

        _TimerThree = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateTask3) userInfo:nil repeats:YES];

    });

    NSLog(@"---- end ----");

}

 

 

- (void)updateUI {

    if (_taskOneIndex < 5) {

        _taskOneIndex += 1;

        _taskOne.text = [NSString stringWithFormat:@"%d", _taskOneIndex];

        NSLog(@"任务1 --- %@ %d", [NSThread currentThread], _taskOneIndex);

    } else {

        [_TimerOne invalidate];

        _TimerOne = NULL;

        _taskOneIndex = 0;

        _queue1 = NULL;

    }

}

 

- (void)updateTask2 {

    if (_taskTwoIndex < 5) {

        _taskTwoIndex += 1;

        _taskTwo.text = [NSString stringWithFormat:@"%d", _taskTwoIndex];

        NSLog(@"任务2 --- %@ %d", [NSThread currentThread], _taskTwoIndex);

    } else {

        [_TimerTwo invalidate];

        _TimerTwo = NULL;

        _taskTwoIndex = 0;

    }

}

 

- (void)updateTask3 {

    if (_taskThreeIndex < 5) {

        _taskThreeIndex += 1;

        _taskThree.text = [NSString stringWithFormat:@"%d", _taskThreeIndex];

        NSLog(@"任务3 --- %@ %d", [NSThread currentThread], _taskThreeIndex);

    } else {

        [_TimerThree invalidate];

        _TimerThree = NULL;

        _taskThreeIndex = 0;

    }

}

@end

 

 

#import <UIKit/UIKit.h>

 

@interface SecondViewController : UIViewController

 

@end

#import "SecondViewController.h"

 

@interface SecondViewController ()

@property (weak, nonatomic) IBOutlet UILabel *label;

 

@end

 

@implementation SecondViewController

 

- (void)viewDidLoad {

    [super viewDidLoad];

}

 

- (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];

}

 

- (IBAction)globalQueue:(id)sender {

    //全局并发队列, 实际上还是main线程,因此如果尝试动态刷新ui,只能更新最终执行的结果,中间步骤会被覆盖。

    //default

    dispatch_queue_t globalQueue1 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    NSLog(@"--- 任务执行前 ---");

    

    dispatch_sync(globalQueue1, ^{

        //因为此处是同步的,所以还是会在主线程中执行,因此打印出来的结果是main

        NSLog(@"-- current thread is %@ --", [NSThread currentThread]);

        //全局并发队列同步执行任务,在主线程执行会造成界面卡顿,这里模拟了耗时操作

        sleep(2);

        NSLog(@"--- 开始执行任务 ---");

        _label.text = @"开始执行任务";

    });

    NSLog(@"--- 任务执行完毕 ---");

    _label.text = @"任务执行完毕";

    

    //    //high

    //    dispatch_queue_t globalQueue2 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);

    //    //low

    //    dispatch_queue_t globalQueue3 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);

    //    //background

    //    dispatch_queue_t globalQueue4 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);

    

    

}

 

- (IBAction)globalAsyn:(id)sender {

    //全局并发队列, 实际上还是main线程,因此如果尝试动态刷新ui,只能更新最终执行的结果,中间步骤会被覆盖。

    //default

    dispatch_queue_t globalQueue1 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    //获取的是主线程

    NSLog(@"--- 任务执行前 ---");

    //dispatch_queue_t mainQueue = dispatch_get_main_queue();

    dispatch_async(globalQueue1, ^{

        //因为此处是异步的,所以打印出来的线程不是主线程,不会堵塞主线程,即便sleep了一段时间

        NSLog(@"-- new async thread is %@ --", [NSThread currentThread]);

        //全局并发队列异步执行任务,其实是创建了新的线程,所以不会造成界面的卡顿,但是因为global是并发的,所以会先执行完执行任务前和执行完毕,最后才是异步操作中的,因为此处已经是子线程,所以无法更新ui,

        //可以切换到主线程来实习最终的效果

        sleep(2);

        //        dispatch_async(mainQueue, ^{

        //            _label.text = @"开始执行任务";

        //

        //        });

        NSLog(@"--- 开始执行任务 ---");

        

    });

    NSLog(@"--- 任务执行完毕 ---");

    _label.text = @"任务执行完毕";

}

 

- (IBAction)groupQueue:(id)sender {

    //使用场景: 同时下载多个图片,所有图片下载完成之后去更新UI(需要回到主线程)或者去处理其他任务(可以是其他线程队列)。当遇到需要执行多个线程并发执行,然后等多个线程都结束之后,再汇总执行结果时可以用group queue

    //原理:使用函数dispatch_group_create创建dispatch group,然后使用函数dispatch_group_async来将要执行的block任务提交到一个dispatch queue。同时将他们添加到一个组,等要执行的block任务全部执行完成之后,使用dispatch_group_notify函数接收完成时的消息。

    dispatch_queue_t conCurrentGlobalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    dispatch_queue_t mainQueue = dispatch_get_main_queue();

    dispatch_group_t groupQueue = dispatch_group_create();

    

    //因为是异步并发的,所以打印的结果是会先打印出来current task 和 next task, 然后才会回来执行block人物,最终等全部的任务结束后会自动调用dispatch_group_notify方法来通知可以更行ui

    NSLog(@"current task");

    dispatch_group_async(groupQueue, conCurrentGlobalQueue, ^{

        NSLog(@"并行任务1");

    });

    

    dispatch_group_async(groupQueue, conCurrentGlobalQueue, ^{

        NSLog(@"并行任务2");

    });

    

    dispatch_group_notify(groupQueue, mainQueue, ^{

        NSLog(@"groupQueue中的人物都执行完成了,回到主线程更新ui");

    });

    NSLog(@"next task");

}

 

@end

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值