gcd 实际例子编写

来源:互联网 发布:python刷题原理 编辑:程序博客网 时间:2024/05/01 19:04

#import "ViewController.h"


@interface ViewController ()

@property (weak,nonatomic) IBOutletUILabel *taskOne;

@property (weak,nonatomic) IBOutletUILabel *taskTwo;

@property (weak,nonatomic) IBOutletUILabel *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 {

    [superviewDidLoad];

}


- (void)didReceiveMemoryWarning {

    [superdidReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}


- (IBAction)asyncConcurrent:(id)sender {

    //   解释

    //   异步执行意味着

    //   可以开启新的线程

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

    //   并行队列意味着

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

    //   两者组合后的结果

    //   开了三个新线程

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

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

    

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

    _queue1 =dispatch_queue_create("ASYNC_CONCURRENT",DISPATCH_QUEUE_CONCURRENT);

    

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

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

    dispatch_async(_queue1, ^{

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

        NSLog(@" -- current thread if on main thread --- %d", [[NSThreadcurrentThread] isEqual:[NSThreadmainThread]]);

        dispatch_queue_t mainQueue =dispatch_get_main_queue();

        dispatch_async(mainQueue,^{

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

            _TimerOne = [NSTimerscheduledTimerWithTimeInterval:1.0ftarget:selfselector:@selector(updateUI)userInfo:nilrepeats:YES];

        });

    });

    

    dispatch_async(_queue1, ^{

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

        NSLog(@" -- current thread if on main thread --- %d", [[NSThreadcurrentThread] isEqual:[NSThreadmainThread]]);

        dispatch_queue_t mainQueue =dispatch_get_main_queue();

        dispatch_async(mainQueue,^{

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

            _TimerTwo = [NSTimerscheduledTimerWithTimeInterval:1.0ftarget:selfselector:@selector(updateTask2)userInfo:nilrepeats:YES];

        });

    });

    

    dispatch_async(_queue1, ^{

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

        NSLog(@" -- current thread if on main thread --- %d", [[NSThreadcurrentThread] isEqual:[NSThreadmainThread]]);

        dispatch_queue_t mainQueue =dispatch_get_main_queue();

        dispatch_async(mainQueue,^{

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

            _TimerThree = [NSTimerscheduledTimerWithTimeInterval:1.0ftarget:selfselector:@selector(updateTask3)userInfo:nilrepeats:YES];

        });

    });

    

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

}


- (IBAction)asyncSerial:(id)sender {

    //   解释

    //   异步执行意味着

    //   可以开启新的线程

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

    //   串行队列意味着

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

    //   两者组合后的结果

    //   开了一个新的子线程

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

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

    

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

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

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

    dispatch_async(queue, ^{

        //一样开启了新的线程

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

        NSLog(@" -- current thread if on main thread --- %d", [[NSThreadcurrentThread] isEqual:[NSThreadmainThread]]);

        dispatch_queue_t mainQueue =dispatch_get_main_queue();

        dispatch_async(mainQueue,^{

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

            _TimerOne = [NSTimerscheduledTimerWithTimeInterval:1.0ftarget:selfselector:@selector(updateUI)userInfo:nilrepeats:YES];

        });

    });

    

    dispatch_async(queue, ^{

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

        NSLog(@" -- current thread if on main thread --- %d", [[NSThreadcurrentThread] isEqual:[NSThreadmainThread]]);

        dispatch_queue_t mainQueue =dispatch_get_main_queue();

        dispatch_async(mainQueue,^{

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

            _TimerTwo = [NSTimerscheduledTimerWithTimeInterval:1.0ftarget:selfselector:@selector(updateTask2)userInfo:nilrepeats:YES];

        });

    });

    

    dispatch_async(queue, ^{

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

        NSLog(@" -- current thread if on main thread --- %d", [[NSThreadcurrentThread] isEqual:[NSThreadmainThread]]);

        dispatch_queue_t mainQueue =dispatch_get_main_queue();

        dispatch_async(mainQueue,^{

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

            _TimerThree = [NSTimerscheduledTimerWithTimeInterval:1.0ftarget:selfselector:@selector(updateTask3)userInfo:nilrepeats: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 --- %@", [NSThreadcurrentThread]);

        NSLog(@" -- current thread if on main thread --- %d", [[NSThreadcurrentThread] isEqual:[NSThreadmainThread]]);

        _TimerOne = [NSTimerscheduledTimerWithTimeInterval:1.0ftarget:selfselector:@selector(updateUI)userInfo:nilrepeats:YES];

    });

    

    dispatch_sync(_queue1, ^{

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

        NSLog(@" -- current thread if on main thread --- %d", [[NSThreadcurrentThread] isEqual:[NSThreadmainThread]]);

        _TimerTwo = [NSTimerscheduledTimerWithTimeInterval:1.0ftarget:selfselector:@selector(updateTask2)userInfo:nilrepeats:YES];

    });

    

    dispatch_sync(_queue1, ^{

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

        NSLog(@" -- current thread if on main thread --- %d", [[NSThreadcurrentThread] isEqual:[NSThreadmainThread]]);

        _TimerThree = [NSTimerscheduledTimerWithTimeInterval:1.0ftarget:selfselector:@selector(updateTask3)userInfo:nilrepeats: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 --- %@", [NSThreadcurrentThread]);

        NSLog(@" -- current thread if on main thread --- %d", [[NSThreadcurrentThread] isEqual:[NSThreadmainThread]]);

        _TimerOne = [NSTimerscheduledTimerWithTimeInterval:1.0ftarget:selfselector:@selector(updateUI)userInfo:nilrepeats:YES];

    });

    

    dispatch_sync(_queue1, ^{

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

        NSLog(@" -- current thread if on main thread --- %d", [[NSThreadcurrentThread] isEqual:[NSThreadmainThread]]);

        _TimerTwo = [NSTimerscheduledTimerWithTimeInterval:1.0ftarget:selfselector:@selector(updateTask2)userInfo:nilrepeats:YES];

    });

    

    dispatch_sync(_queue1, ^{

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

        NSLog(@" -- current thread if on main thread --- %d", [[NSThreadcurrentThread] isEqual:[NSThreadmainThread]]);

        _TimerThree = [NSTimerscheduledTimerWithTimeInterval:1.0ftarget:selfselector:@selector(updateTask3)userInfo:nilrepeats:YES];

    });

    

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

}


- (IBAction)asyncMain:(id)sender {

//    解释

//    异步执行意味着

//    可以开启新的线程

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

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

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

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

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

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

    _queue1 =dispatch_get_main_queue();

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

    dispatch_async(_queue1, ^{

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

        NSLog(@" -- current thread if on main thread --- %d", [[NSThreadcurrentThread] isEqual:[NSThreadmainThread]]);

        _TimerOne = [NSTimerscheduledTimerWithTimeInterval:1.0ftarget:selfselector:@selector(updateUI)userInfo:nilrepeats:YES];

    });

    

    dispatch_async(_queue1, ^{

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

        NSLog(@" -- current thread if on main thread --- %d", [[NSThreadcurrentThread] isEqual:[NSThreadmainThread]]);

        _TimerTwo = [NSTimerscheduledTimerWithTimeInterval:1.0ftarget:selfselector:@selector(updateTask2)userInfo:nilrepeats:YES];

    });

    

    dispatch_async(_queue1, ^{

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

        NSLog(@" -- current thread if on main thread --- %d", [[NSThreadcurrentThread] isEqual:[NSThreadmainThread]]);

        _TimerThree = [NSTimerscheduledTimerWithTimeInterval:1.0ftarget:selfselector:@selector(updateTask3)userInfo:nilrepeats:YES];

    });

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

}


- (IBAction)syncMain:(id)sender {

    _queue1 =dispatch_get_main_queue();

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

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

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

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

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

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

    dispatch_sync(_queue1, ^{

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

        NSLog(@" -- current thread if on main thread --- %d", [[NSThreadcurrentThread] isEqual:[NSThreadmainThread]]);

        _TimerOne = [NSTimerscheduledTimerWithTimeInterval:1.0ftarget:selfselector:@selector(updateUI)userInfo:nilrepeats:YES];

    });

    

    dispatch_sync(_queue1, ^{

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

        NSLog(@" -- current thread if on main thread --- %d", [[NSThreadcurrentThread] isEqual:[NSThreadmainThread]]);

        _TimerTwo = [NSTimerscheduledTimerWithTimeInterval:1.0ftarget:selfselector:@selector(updateTask2)userInfo:nilrepeats:YES];

    });

    

    dispatch_sync(_queue1, ^{

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

        NSLog(@" -- current thread if on main thread --- %d", [[NSThreadcurrentThread] isEqual:[NSThreadmainThread]]);

        _TimerThree = [NSTimerscheduledTimerWithTimeInterval:1.0ftarget:selfselector:@selector(updateTask3)userInfo:nilrepeats:YES];

    });

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

}



- (void)updateUI {

    if (_taskOneIndex < 5) {

        _taskOneIndex += 1;

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

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

    } else {

        [_TimerOneinvalidate];

        _TimerOne =NULL;

        _taskOneIndex = 0;

        _queue1 =NULL;

    }

}


- (void)updateTask2 {

    if (_taskTwoIndex < 5) {

        _taskTwoIndex += 1;

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

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

    } else {

        [_TimerTwoinvalidate];

        _TimerTwo =NULL;

        _taskTwoIndex = 0;

    }

}


- (void)updateTask3 {

    if (_taskThreeIndex < 5) {

        _taskThreeIndex += 1;

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

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

    } else {

        [_TimerThreeinvalidate];

        _TimerThree =NULL;

        _taskThreeIndex = 0;

    }

}

@end


#import <UIKit/UIKit.h>


@interface SecondViewController :UIViewController


@end

#import "SecondViewController.h"


@interface SecondViewController ()

@property (weak,nonatomic) IBOutletUILabel *label;


@end


@implementation SecondViewController


- (void)viewDidLoad {

    [superviewDidLoad];

}


- (void)didReceiveMemoryWarning {

    [superdidReceiveMemoryWarning];

}


- (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 %@ --", [NSThreadcurrentThread]);

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

        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 %@ --", [NSThreadcurrentThread]);

        //全局并发队列异步执行任务,其实是创建了新的线程,所以不会造成界面的卡顿,但是因为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






原创粉丝点击