iOS之GCD再谈(dispatch_group,dispatch_semaphore)

所有的话都在代码里了,仔细一个一个测下来理解体会肯定会有收获哦!

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    //[self test1];
    //[self test2];
    //[self test3];
    //[self test4];
    //[self test6];
    [self test7];
}

//1.异步下载图片
-(void)test1
{
    UIImageView *imageView=[[UIImageView alloc]init];
    imageView.frame=CGRectMake(40, 40, 200, 200);
    imageView.contentMode=UIViewContentModeScaleToFill;
    [self.view addSubview:imageView];
    
    NSString *url=@"http://www.nbdpc.gov.cn/picture/0/s20160302140316.jpg";
    NSURL *imageUrl=[NSURL URLWithString:url];
    
    //并行队列
    dispatch_queue_t queue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    //当我们有一个耗时的事情,应该放到后台队列中去做,等做完了通知UI,是不会阻塞UI,降低用户体验的。
    dispatch_async(queue, ^{
        
        NSData *data=[NSData dataWithContentsOfURL:imageUrl];
        UIImage *image=[UIImage imageWithData:data];
        
        if (image)
        {
            //sleep(2);
            dispatch_async(dispatch_get_main_queue(), ^{
                imageView.image=image;
            });
        }
    });
}

//2.并行队列/串行队列(过程不想关的任务,提交到并行的队列中会显著提高效率)
-(void)test2
{
//    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//        
//        for(int i=0;i<5;i++)
//        {
//            NSLog(@"First task:%d",i);
//            sleep(1);
//        }
//    });
//    
//    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//        
//        for(int i=0;i<5;i++)
//        {
//            NSLog(@"Second task:%d",i);
//            sleep(1);
//        }
//    });
    
    dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        
        for(int i=0;i<5;i++)
        {
            NSLog(@"First task:%d",i);
            sleep(1);
        }
    });
    
    dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        
        for(int i=0;i<5;i++)
        {
            NSLog(@"Second task:%d",i);
            sleep(1);
        }
    });
}

//3.dispatch_after
/*
 (延迟一段时间把一项任务添加到队列中去执行)
 不是一定时间后执行相应的任务,而是一定时间后,将执行的操作加入到队列中(队列里面再分配执行的时间)
 */
-(void)test3
{
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10ull * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        
        NSLog(@"after 10s");
    });
}

//4.dispatch_apply:
/*
 1.把一项任务提交到队列中多次执行,具体是并行执行还是串行执行由队列本身决定。
 2.dispatch_apply不会立刻返回,在执行完毕后才会返回,是同步的调用
 3.通过追踪发现它运行在主线程,而下文又与dispatch_apply的执行结果无关,所以可以在异步队列中调dispatch_apply
 */
-(void)test4
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        
        dispatch_queue_t queue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        //dispatch_queue_t queue=dispatch_queue_create("gu", DISPATCH_QUEUE_SERIAL);
        
        dispatch_apply(10, queue, ^(size_t index) {
            
            NSLog(@"%zu %@",index,[NSThread currentThread]);
        });
        //NSLog(@"done");
        dispatch_async(queue, ^{
            NSLog(@"123 %@",[NSThread currentThread]);
        });
        dispatch_async(queue, ^{
            NSLog(@"321 %@",[NSThread currentThread]);
        });
    });
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        
        NSLog(@"继续执行%@",[NSThread currentThread]);
    });
}

//5.dispatch_once:保证在运行期间,block中的代码只执行一次


//6.dispatch_group
/*
 1.dispatch_group_create 创建一个调度任务组
 2.dispatch_group_async  把一个任务异步提交到任务组里
 3.dispatch_group_notify 用来监听任务组事件的监听完毕
 4.dispatch_group_wait   设置等待时间,在等待时间结束后,如果还没有执行完任务组,则返回(0代表执行成功)
 */
-(void)test6
{
    //创建group
    dispatch_group_t group=dispatch_group_create();
    //全局队列,这个队列为并行队列
    dispatch_queue_t globalQueue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    //创建一个用户队列,串行的
    dispatch_queue_t userQueue=dispatch_queue_create("gujinyue", DISPATCH_QUEUE_SERIAL);
    
    
    dispatch_group_async(group, globalQueue, ^{
        
       // sleep(3);
        NSLog(@"Task1 is done");
    });
    
    dispatch_group_async(group, globalQueue, ^{
        
        //sleep(3);
        NSLog(@"Task11 is done");
    });

    dispatch_group_async(group, globalQueue, ^{
        
        //sleep(3);
        NSLog(@"Task111 is done");
    });
    
    dispatch_group_async(group, globalQueue, ^{
        
        //sleep(3);
        NSLog(@"Task1111 is done");
    });
    
    dispatch_group_async(group, globalQueue, ^{
        
        //sleep(3);
        NSLog(@"Task11111 is done");
    });

    
    dispatch_group_async(group, userQueue, ^{
        
        //sleep(3);
        NSLog(@"Task2 is done");
    });
    
    dispatch_group_async(group, userQueue, ^{
        
        //sleep(3);
        NSLog(@"Task3 is done");
    });
    
    
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        
        NSLog(@"所有任务执行完后来到这里%@",[NSThread currentThread]);
        for(int i=0;i<5;i++)
        {
            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
                
                NSLog(@"%d",i);
            });
        }
    });
}

//7.dispatch_semaphore(信号量)
/*
 1.信号量是一个整形值并且具有一个初始计数值。
 2.简单来说就是控制访问有限资源的线程数量,比如有两个资源可以被利用,同时有三个线程要访问,第三个应当等待资源被释放后再访问。
 3.创建一个信号量:dispatch_semaphore_create
   提高一个信号量:dispatch_semaphore_signal
   降低一个信号量:dispatch_semaphore_wait
 
 */
-(void)test7
{
    //可以分别测试一下信号量为1,2,3的时候,比较一下
    dispatch_semaphore_t semaphore=dispatch_semaphore_create(3);
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"First task is starting");
        sleep(3);
        NSLog(@"First task is done");
        sleep(3);
        dispatch_semaphore_signal(semaphore);
    });
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"Second task is starting");
        sleep(3);
        NSLog(@"Second task is done");
        sleep(3);
        dispatch_semaphore_signal(semaphore);
    });
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"Third task is starting");
        sleep(3);
        NSLog(@"Thrid task is done");
        sleep(3);
        dispatch_semaphore_signal(semaphore);
    });
}
@end


你可能感兴趣的:(iOS,iOS开发)