GCD的一些测试和总结

1-创建、获取队列

主要测试

1.dispatch_queue_create

2.dispatch_sync

3.dispatch_async

4.dispatch_get_main_queue

5.dispatch_get_global_queue

//
//  ViewController.m
//  GCDDemo
//
//  Created by gongzixiaobai on 16/3/19.
//  Copyright ? 2016年 公子小白. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{

    [self gcdTest7];

}

#pragma mark - GCD API 测试
// step1 :测试dispatch_queue_create和dispatch_async
/**************************************************step1-start*************************************************************/

/*
 测试总结:

 *任务提交方式(sync、async)和队列的属性(DISPATCH_QUEUE_SERIAL、DISPATCH_QUEUE_CONCURRENT)对任务执行(顺序和所在线程)的影响

 只要队列中有任务就会立即执行,
 a)sync 方式提交的会立即在当前线程执行(会阻塞当前线程,与当前线程间有先后顺序),
 b)async 方式提交的会在其它线程执行(具体开多少条线程由GCD系统管理)并与当前线程并发执行(与当前线程没有先后顺序)
 c)DISPATCH_QUEUE_SERIAL决定了队列中的任务只能顺序执行(不论用sync还是async方式提交)
 d)DISPATCH_QUEUE_CONCURRENT决定了队列中的任务可以顺序执行(sync方式提交)也可以乱序执行(async方式提交)
 e)串行队列最多只会创建一个线程(用async提交)并行队列可以创建多个具体由GCD系统决定(用async提交)

 */

//- (void)gcdTest4
//{
//    //1. 并行队列
//    dispatch_queue_t queue = dispatch_queue_create("xiaobai", DISPATCH_QUEUE_CONCURRENT);
//
//    // 2. 异步执行任务
//    for (int i = 0; i < 10; i++) {
//        dispatch_async(queue, ^{
//            NSLog(@"%@ %d", [NSThread currentThread], i);
//        });
//    }
//
//
//    NSLog(@"========");
//    /*
//     2016-03-19 14:54:17.727 GCDDemo[9112:751722] ========
//     2016-03-19 14:54:17.728 GCDDemo[9112:759447] <NSThread: 0x7f934a458700>{number = 26, name = (null)} 0
//     2016-03-19 14:54:17.728 GCDDemo[9112:759445] <NSThread: 0x7f934a51da60>{number = 27, name = (null)} 1
//     2016-03-19 14:54:17.728 GCDDemo[9112:759453] <NSThread: 0x7f934a4ad580>{number = 28, name = (null)} 2
//     2016-03-19 14:54:17.728 GCDDemo[9112:759454] <NSThread: 0x7f934a43e390>{number = 29, name = (null)} 3
//     2016-03-19 14:54:17.728 GCDDemo[9112:759447] <NSThread: 0x7f934a458700>{number = 26, name = (null)} 4
//     2016-03-19 14:54:17.729 GCDDemo[9112:759456] <NSThread: 0x7f934a50fd20>{number = 30, name = (null)} 5
//     2016-03-19 14:54:17.729 GCDDemo[9112:759445] <NSThread: 0x7f934a51da60>{number = 27, name = (null)} 6
//     2016-03-19 14:54:17.729 GCDDemo[9112:759458] <NSThread: 0x7f934a5083e0>{number = 31, name = (null)} 7
//     2016-03-19 14:54:17.729 GCDDemo[9112:759460] <NSThread: 0x7f934a520110>{number = 32, name = (null)} 8
//     2016-03-19 14:54:17.730 GCDDemo[9112:759453] <NSThread: 0x7f934a4ad580>{number = 28, name = (null)} 9
//
//     2016-03-19 14:54:23.083 GCDDemo[9112:760048] <NSThread: 0x7f934a51da60>{number = 34, name = (null)} 1
//     2016-03-19 14:54:23.083 GCDDemo[9112:760044] <NSThread: 0x7f934a507430>{number = 33, name = (null)} 0
//     2016-03-19 14:54:23.083 GCDDemo[9112:760046] <NSThread: 0x7f934a703160>{number = 35, name = (null)} 2
//     2016-03-19 14:54:23.083 GCDDemo[9112:760054] <NSThread: 0x7f934a50fd20>{number = 36, name = (null)} 3
//     2016-03-19 14:54:23.084 GCDDemo[9112:760048] <NSThread: 0x7f934a51da60>{number = 34, name = (null)} 4
//     2016-03-19 14:54:23.083 GCDDemo[9112:751722] ========
//     2016-03-19 14:54:23.084 GCDDemo[9112:760044] <NSThread: 0x7f934a507430>{number = 33, name = (null)} 5
//     2016-03-19 14:54:23.084 GCDDemo[9112:760046] <NSThread: 0x7f934a703160>{number = 35, name = (null)} 6
//     2016-03-19 14:54:23.084 GCDDemo[9112:760054] <NSThread: 0x7f934a50fd20>{number = 36, name = (null)} 7
//     2016-03-19 14:54:23.084 GCDDemo[9112:760048] <NSThread: 0x7f934a51da60>{number = 34, name = (null)} 8
//     2016-03-19 14:54:23.084 GCDDemo[9112:760044] <NSThread: 0x7f934a507430>{number = 33, name = (null)} 9
//
//
//
//     */
//
//}

//-(void)gcdTest3
//{
//
//    dispatch_queue_t aqueue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT);
//    for (int i = 0; i<10; i++) {
//        dispatch_sync(aqueue, ^{
//            NSLog(@"%@,%d",[NSThread currentThread],i);
//        });
//    }
//
//    NSLog(@"=======");
//    /*
//     2016-03-19 14:51:14.429 GCDDemo[8943:734337] <NSThread: 0x7fa6a0e02ac0>{number = 1, name = main},0
//     2016-03-19 14:51:14.430 GCDDemo[8943:734337] <NSThread: 0x7fa6a0e02ac0>{number = 1, name = main},1
//     2016-03-19 14:51:14.430 GCDDemo[8943:734337] <NSThread: 0x7fa6a0e02ac0>{number = 1, name = main},2
//     2016-03-19 14:51:14.430 GCDDemo[8943:734337] <NSThread: 0x7fa6a0e02ac0>{number = 1, name = main},3
//     2016-03-19 14:51:14.430 GCDDemo[8943:734337] <NSThread: 0x7fa6a0e02ac0>{number = 1, name = main},4
//     2016-03-19 14:51:14.430 GCDDemo[8943:734337] <NSThread: 0x7fa6a0e02ac0>{number = 1, name = main},5
//     2016-03-19 14:51:14.430 GCDDemo[8943:734337] <NSThread: 0x7fa6a0e02ac0>{number = 1, name = main},6
//     2016-03-19 14:51:14.431 GCDDemo[8943:734337] <NSThread: 0x7fa6a0e02ac0>{number = 1, name = main},7
//     2016-03-19 14:51:14.431 GCDDemo[8943:734337] <NSThread: 0x7fa6a0e02ac0>{number = 1, name = main},8
//     2016-03-19 14:51:14.431 GCDDemo[8943:734337] <NSThread: 0x7fa6a0e02ac0>{number = 1, name = main},9
//     2016-03-19 14:51:14.431 GCDDemo[8943:734337] =======
//
//
//     */
//}

//-(void)gcdTest2
//{
//
//    dispatch_queue_t aqueue = dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL);
//    for (int i = 0; i<10; i++) {
//        dispatch_async(aqueue, ^{
//            NSLog(@"%@,%d",[NSThread currentThread],i);
//        });
//    }
//
//    NSLog(@"=======");
//    /*
//
//     2016-03-19 14:45:50.022 GCDDemo[8603:695116] =======
//     2016-03-19 14:45:50.022 GCDDemo[8603:699491] <NSThread: 0x7fe6e1e283d0>{number = 4, name = (null)},0
//     2016-03-19 14:45:50.023 GCDDemo[8603:699491] <NSThread: 0x7fe6e1e283d0>{number = 4, name = (null)},1
//     2016-03-19 14:45:50.023 GCDDemo[8603:699491] <NSThread: 0x7fe6e1e283d0>{number = 4, name = (null)},2
//     2016-03-19 14:45:50.024 GCDDemo[8603:699491] <NSThread: 0x7fe6e1e283d0>{number = 4, name = (null)},3
//     2016-03-19 14:45:50.024 GCDDemo[8603:699491] <NSThread: 0x7fe6e1e283d0>{number = 4, name = (null)},4
//     2016-03-19 14:45:50.024 GCDDemo[8603:699491] <NSThread: 0x7fe6e1e283d0>{number = 4, name = (null)},5
//     2016-03-19 14:45:50.024 GCDDemo[8603:699491] <NSThread: 0x7fe6e1e283d0>{number = 4, name = (null)},6
//     2016-03-19 14:45:50.025 GCDDemo[8603:699491] <NSThread: 0x7fe6e1e283d0>{number = 4, name = (null)},7
//     2016-03-19 14:45:50.025 GCDDemo[8603:699491] <NSThread: 0x7fe6e1e283d0>{number = 4, name = (null)},8
//     2016-03-19 14:45:50.025 GCDDemo[8603:699491] <NSThread: 0x7fe6e1e283d0>{number = 4, name = (null)},9
//
//     2016-03-19 14:45:50.191 GCDDemo[8603:699491] <NSThread: 0x7fe6e1e283d0>{number = 4, name = (null)},0
//     2016-03-19 14:45:50.192 GCDDemo[8603:699491] <NSThread: 0x7fe6e1e283d0>{number = 4, name = (null)},1
//     2016-03-19 14:45:50.192 GCDDemo[8603:699491] <NSThread: 0x7fe6e1e283d0>{number = 4, name = (null)},2
//     2016-03-19 14:45:50.191 GCDDemo[8603:695116] =======
//     2016-03-19 14:45:50.192 GCDDemo[8603:699491] <NSThread: 0x7fe6e1e283d0>{number = 4, name = (null)},3
//     2016-03-19 14:45:50.192 GCDDemo[8603:699491] <NSThread: 0x7fe6e1e283d0>{number = 4, name = (null)},4
//     2016-03-19 14:45:50.193 GCDDemo[8603:699491] <NSThread: 0x7fe6e1e283d0>{number = 4, name = (null)},5
//     2016-03-19 14:45:50.193 GCDDemo[8603:699491] <NSThread: 0x7fe6e1e283d0>{number = 4, name = (null)},6
//     2016-03-19 14:45:50.193 GCDDemo[8603:699491] <NSThread: 0x7fe6e1e283d0>{number = 4, name = (null)},7
//     2016-03-19 14:45:50.194 GCDDemo[8603:699491] <NSThread: 0x7fe6e1e283d0>{number = 4, name = (null)},8
//     2016-03-19 14:45:50.194 GCDDemo[8603:699491] <NSThread: 0x7fe6e1e283d0>{number = 4, name = (null)},9
//
//     */
//
//}

//-(void)gcdTest1
//{
//
//    dispatch_queue_t aqueue = dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL);
//    for (int i = 0; i<10; i++) {
//        dispatch_sync(aqueue, ^{
//            NSLog(@"%@,%d",[NSThread currentThread],i);
//        });
//    }
//
//    NSLog(@"=======");
//    /*
//
//     dispatch_sync提交的任务会阻塞当前任务,它会先执行,完了再向下执行
//
//
//     2016-03-19 14:21:13.531 GCDDemo[7089:575399] <NSThread: 0x7febd1f03530>{number = 1, name = main},0
//     2016-03-19 14:21:13.532 GCDDemo[7089:575399] <NSThread: 0x7febd1f03530>{number = 1, name = main},1
//     2016-03-19 14:21:13.532 GCDDemo[7089:575399] <NSThread: 0x7febd1f03530>{number = 1, name = main},2
//     2016-03-19 14:21:13.532 GCDDemo[7089:575399] <NSThread: 0x7febd1f03530>{number = 1, name = main},3
//     2016-03-19 14:21:13.532 GCDDemo[7089:575399] <NSThread: 0x7febd1f03530>{number = 1, name = main},4
//     2016-03-19 14:21:13.533 GCDDemo[7089:575399] <NSThread: 0x7febd1f03530>{number = 1, name = main},5
//     2016-03-19 14:21:13.533 GCDDemo[7089:575399] <NSThread: 0x7febd1f03530>{number = 1, name = main},6
//     2016-03-19 14:21:13.533 GCDDemo[7089:575399] <NSThread: 0x7febd1f03530>{number = 1, name = main},7
//     2016-03-19 14:21:13.533 GCDDemo[7089:575399] <NSThread: 0x7febd1f03530>{number = 1, name = main},8
//     2016-03-19 14:21:13.533 GCDDemo[7089:575399] <NSThread: 0x7febd1f03530>{number = 1, name = main},9
//     2016-03-19 14:21:13.533 GCDDemo[7089:575399] =======
//
//     */
//
//}

/**************************************************step1-end*************************************************************/

// step2 :测试dispatch_get_main_queue();、dispatch_get_global_queue
/*
 总结:
 全局队列 跟 并发队列的 区别
 1. 全局队列没有名称 并发队列有名称
 2. 全局队列,是供所有的应用程序共享。
 3. 在MRC开发,并发队列,创建完了,需要释放。 全局队列不需要我们管理
 */

/**************************************************step2-start*************************************************************/

/**
 * sync提交任务到主队列会发生死锁,async提交任务到主队列会等主线程中任务处理完在执行提交的任务
 */

- (void)gcdTest5
{

    // 1. 获得主队列-> 程序启动,--> 至少有一个主线程-> 一开始就会创建主队列
    dispatch_queue_t queue = dispatch_get_main_queue();

    NSLog(@"1----");

    // 2. 异步执行任务
    for (int i = 0; i < 10; i++) {
        NSLog(@"调度前---");
        // 异步:把任务放到主队列里,但是不需要马上执行
        dispatch_async(queue, ^{
            NSLog(@"%@ %d", [NSThread currentThread], i);
        });
        NSLog(@"睡会");
        [NSThread sleepForTimeInterval:2.0];
    }
    NSLog(@"完成----");
    /*
     2016-03-19 16:46:10.151 GCDDemo[15481:1177084] 1----
     2016-03-19 16:46:10.151 GCDDemo[15481:1177084] 调度前---
     2016-03-19 16:46:10.152 GCDDemo[15481:1177084] 睡会
     2016-03-19 16:46:12.152 GCDDemo[15481:1177084] 调度前---
     2016-03-19 16:46:12.153 GCDDemo[15481:1177084] 睡会
     2016-03-19 16:46:14.153 GCDDemo[15481:1177084] 调度前---
     2016-03-19 16:46:14.154 GCDDemo[15481:1177084] 睡会
     2016-03-19 16:46:16.155 GCDDemo[15481:1177084] 调度前---
     2016-03-19 16:46:16.155 GCDDemo[15481:1177084] 睡会
     2016-03-19 16:46:18.156 GCDDemo[15481:1177084] 调度前---
     2016-03-19 16:46:18.157 GCDDemo[15481:1177084] 睡会
     2016-03-19 16:46:20.157 GCDDemo[15481:1177084] 调度前---
     2016-03-19 16:46:20.157 GCDDemo[15481:1177084] 睡会
     2016-03-19 16:46:22.158 GCDDemo[15481:1177084] 调度前---
     2016-03-19 16:46:22.159 GCDDemo[15481:1177084] 睡会
     2016-03-19 16:46:24.160 GCDDemo[15481:1177084] 调度前---
     2016-03-19 16:46:24.160 GCDDemo[15481:1177084] 睡会
     2016-03-19 16:46:26.161 GCDDemo[15481:1177084] 调度前---
     2016-03-19 16:46:26.162 GCDDemo[15481:1177084] 睡会
     2016-03-19 16:46:28.163 GCDDemo[15481:1177084] 调度前---
     2016-03-19 16:46:28.164 GCDDemo[15481:1177084] 睡会
     2016-03-19 16:46:30.165 GCDDemo[15481:1177084] 完成----
     2016-03-19 16:46:30.166 GCDDemo[15481:1177084] <NSThread: 0x7fe7fbe07cc0>{number = 1, name = main} 0
     2016-03-19 16:46:30.185 GCDDemo[15481:1177084] <NSThread: 0x7fe7fbe07cc0>{number = 1, name = main} 1
     2016-03-19 16:46:30.185 GCDDemo[15481:1177084] <NSThread: 0x7fe7fbe07cc0>{number = 1, name = main} 2
     2016-03-19 16:46:30.185 GCDDemo[15481:1177084] <NSThread: 0x7fe7fbe07cc0>{number = 1, name = main} 3
     2016-03-19 16:46:30.186 GCDDemo[15481:1177084] <NSThread: 0x7fe7fbe07cc0>{number = 1, name = main} 4
     2016-03-19 16:46:30.186 GCDDemo[15481:1177084] <NSThread: 0x7fe7fbe07cc0>{number = 1, name = main} 5
     2016-03-19 16:46:30.186 GCDDemo[15481:1177084] <NSThread: 0x7fe7fbe07cc0>{number = 1, name = main} 6
     2016-03-19 16:46:30.186 GCDDemo[15481:1177084] <NSThread: 0x7fe7fbe07cc0>{number = 1, name = main} 7
     2016-03-19 16:46:30.186 GCDDemo[15481:1177084] <NSThread: 0x7fe7fbe07cc0>{number = 1, name = main} 8
     2016-03-19 16:46:30.186 GCDDemo[15481:1177084] <NSThread: 0x7fe7fbe07cc0>{number = 1, name = main} 9
     // 如果把dispatch_async改为dispatch_sync那么程序就会相互等待不会执行

     */

}

// 同步任务的作用
- (void)gcdTest6
{
    // 并发队列
    dispatch_queue_t  queue = dispatch_queue_create("cz", DISPATCH_QUEUE_CONCURRENT);

    /**
     例子:有一个小说网站
     - 必须登录,才能下载小说

     有三个任务:
     1. 用户登录
     2. 下载小说A
     3. 下载小说B
     */
    // 添加任务
    // 同步任务,需要马上执行。 不开新线程
    dispatch_sync(queue, ^{
        NSLog(@"用户登录 %@", [NSThread currentThread]);
    });
    //
    dispatch_async(queue, ^{
        NSLog(@"下载小说A %@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"下载小说B %@", [NSThread currentThread]);
    });
    /*
     2016-03-20 15:24:36.204 GCDDemo[79345:2527098] 用户登录 <NSThread: 0x7f9ee86033a0>{number = 1, name = main}
     2016-03-20 15:24:36.206 GCDDemo[79345:2527592] 下载小说A <NSThread: 0x7f9ee87285d0>{number = 2, name = (null)}
     2016-03-20 15:24:36.206 GCDDemo[79345:2527674] 下载小说B <NSThread: 0x7f9ee8748070>{number = 3, name = (null)}
     */
}
// 全局队列
- (void)gcdTest7
{
    // 获得全局队列
    /**
     参数:第一个参数,一般 写 0(可以适配 iOS 7 & 8)
     iOS 7
     DISPATCH_QUEUE_PRIORITY_HIGH 2  高优先级
     DISPATCH_QUEUE_PRIORITY_DEFAULT 0  默认优先级
     DISPATCH_QUEUE_PRIORITY_LOW (-2) 低优先级
     DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN 后台优先级

     iOS 8
     QOS_CLASS_DEFAULT  0

     第二个参数:保留参数 0
     */
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);

    // 添加异步任务
    for (int i = 0; i < 10; i++) {
        dispatch_async(queue, ^{
            NSLog(@"%@ %d", [NSThread currentThread], i);
        });
    }
    /*
     2016-03-20 15:34:37.200 GCDDemo[79924:2559827] <NSThread: 0x7fea71516490>{number = 5, name = (null)} 3
     2016-03-20 15:34:37.200 GCDDemo[79924:2559828] <NSThread: 0x7fea717139b0>{number = 4, name = (null)} 2
     2016-03-20 15:34:37.200 GCDDemo[79924:2559722] <NSThread: 0x7fea7145d930>{number = 2, name = (null)} 1
     2016-03-20 15:34:37.200 GCDDemo[79924:2559725] <NSThread: 0x7fea71513950>{number = 3, name = (null)} 0
     2016-03-20 15:34:37.200 GCDDemo[79924:2560445] <NSThread: 0x7fea7145c920>{number = 6, name = (null)} 4
     2016-03-20 15:34:37.201 GCDDemo[79924:2559827] <NSThread: 0x7fea71516490>{number = 5, name = (null)} 5
     2016-03-20 15:34:37.201 GCDDemo[79924:2559828] <NSThread: 0x7fea717139b0>{number = 4, name = (null)} 6
     2016-03-20 15:34:37.201 GCDDemo[79924:2559722] <NSThread: 0x7fea7145d930>{number = 2, name = (null)} 7
     2016-03-20 15:34:37.201 GCDDemo[79924:2559725] <NSThread: 0x7fea71513950>{number = 3, name = (null)} 8
     2016-03-20 15:34:37.201 GCDDemo[79924:2560445] <NSThread: 0x7fea7145c920>{number = 6, name = (null)} 9

     */

}

/**************************************************step2-end*************************************************************/
@end

2-线程间通信(重要)

/**
 *  线程间通信没有用到新的API但用到了两个async嵌套的结构
 */
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    dispatch_async(dispatch_get_global_queue(0, 0), ^{

        NSLog(@"%@", [NSThread currentThread]);
        // 耗时操作: 放在全局队列,异步执行
        // 1. url, 确定一个网络上的资源路径
        NSURL *url = [NSURL URLWithString:@"http://fe.topit.me/e/d1/12/1170068721aa112d1el.jpg"];

        // 2. 通过url可以下载对应的网络资源, 网络资源传输的都是二进制
        NSData *data = [NSData dataWithContentsOfURL:url];

        // 3. 二进制转成图片
        UIImage *image = [UIImage imageWithData:data];

        // 4. 更新UI,在主线程-》 直接把任务添加到主队列,就会在主队列执行
        dispatch_async(dispatch_get_main_queue(), ^{
            self.iconView.image = image;
            NSLog(@"-----%@", [NSThread currentThread]);

        });
    });

}

3-管理队列任务

测试

1.dispatch_after

2.dispatch_once

#pragma mark - 延时操作
- (void)delay
{
    /**
     参数:
     now 0
     NSEC_PER_SEC: 很大的数字

     */
    dispatch_time_t when = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC));

    // 参数: when : 表示从现在开始,经过多少纳秒以后
    // queue :  在哪一个队列里面执行后面的任务
//    dispatch_after(when, dispatch_get_main_queue(), ^{
//        NSLog(@"点我了-- %@", [NSThread currentThread]);
//    });
//
    dispatch_after(when, dispatch_get_global_queue(0, 0), ^{
        NSLog(@"点我了-- %@", [NSThread currentThread]);
    });
}

#pragma mark - 一次性执行
- (void)once
{
    static dispatch_once_t onceToken;
    NSLog(@"%ld", onceToken);

    dispatch_once(&onceToken, ^{// 这里的代码只在第一次点击时执行
        NSLog(@"%ld", onceToken);

        NSLog(@"真的执行一次么?");
    });

    NSLog(@"完成");

    /*
     2016-03-21 14:39:45.532 08-GCD的其他用法[2721:1579052] 0
     2016-03-21 14:39:45.533 08-GCD的其他用法[2721:1579052] 140734671969216
     2016-03-21 14:39:45.533 08-GCD的其他用法[2721:1579052] 真的执行一次么?
     2016-03-21 14:39:45.533 08-GCD的其他用法[2721:1579052] 完成
     2016-03-21 14:40:08.774 08-GCD的其他用法[2721:1579052] -1
     2016-03-21 14:40:08.774 08-GCD的其他用法[2721:1579052] 完成
     2016-03-21 14:40:18.730 08-GCD的其他用法[2721:1579052] -1
     2016-03-21 14:40:18.730 08-GCD的其他用法[2721:1579052] 完成
     */
}

4-使用队列组

测试
1.dispatch_group_create
2.dispatch_group_async
3.dispatch_group_notify
4.

#pragma mark - 调度组(分组)
- (void)group
{
    /**
     应用场景:
     开发的时候,有的时候出现多个网络请求都完成以后(每一个网络请求的事件长短不一定),再统一通知用户 

     比如: 下载小说:三国演义, 红楼梦, 金X梅
     */
    // 实例化一个调度组
    dispatch_group_t group = dispatch_group_create();

    // 队列
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);

    // 任务添加到队列queue
    dispatch_group_async(group, queue, ^{
        NSLog(@"下载小说A---%@", [NSThread currentThread]);
    });

    dispatch_group_async(group, queue, ^{
        NSLog(@"下载小说B---%@", [NSThread currentThread]);
    });

    dispatch_group_async(group, queue, ^{
        NSLog(@"下载小说X---%@", [NSThread currentThread]);
    });

    // 获得所有调度组里面的异步任务完成的通知
//    dispatch_group_notify(group, queue, ^{
//        NSLog(@"下载完成,请观看%@", [NSThread currentThread]); // 异步的
//    });

    //注意点: 在调度组完成通知里,可以跨队列通信
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        // 更新UI,在主线程
        NSLog(@"下载完成,请观看%@", [NSThread currentThread]); // 异步的
    });
    /*
     2016-03-21 12:41:32.640 08-GCD的其他用法[2466:1186856] 下载小说B---<NSThread: 0x7fbab241a5d0>{number = 3, name = (null)}
     2016-03-21 12:41:32.640 08-GCD的其他用法[2466:1186855] 下载小说A---<NSThread: 0x7fbab250b090>{number = 2, name = (null)}
     2016-03-21 12:41:32.640 08-GCD的其他用法[2466:1186859] 下载小说X---<NSThread: 0x7fbab240d120>{number = 4, name = (null)}
     2016-03-21 12:41:32.641 08-GCD的其他用法[2466:1186625] 下载完成,请观看<NSThread: 0x7fbab2606d90>{number = 1, name = main}
     */
}
时间: 2024-11-06 01:11:46

GCD的一些测试和总结的相关文章

NSURLConnection同步和异步连接

NSURLConnection去加载一个URL请求时候有两种方式,一种是同步加载,一种是异步加载. 同步加载会阻塞当前的那个线程,如果将同步加载的代码放在主线程里去执行,那么就会阻塞主线程. 异步加载一种方式使用的是block,就算将加载的代码放到主线程去执行,也不会阻塞主线程.异步加载的另一种方式比较灵活.它可以在你需要的时候去启动,在你不需要的时候可以取消. 先看一个在主线程种同步和异步,以及使用GCD同步三种方式加载数据的阻塞情况 // // AppDelegate.m // NSURLC

软件工程项目之二:结对编程——四则运算生成计算程序

0x01 :简介 本次的编程任务是完成一个具有UI界面的,具备四则运算生成.计算.判断对错功能的程序.本次程序使用C#语言编写,用时为2周. 0x02 :软件工程和PSP表格记录 PSP 2.1 Persinal Software Process Stages Time(Estimated) Time(Real) Planning 计划     Estimate 估计这个任务需要多少时间 24h 36h Development 开发     Analysis 需求分析(包括学习新技术) 8~10

辗转相除法的实现

辗转相除法基于如下原理:两个整数的最大公约数等于其中较小的数和两数的相除余数的最大公约数.#include<stdio.h> //使用辗转相除法求最大公约数int gcd(int a, int b){ if (a % b == 0) { printf("%d",b); } else { return gcd(b, a%b); }}int main (void){ gcd(8,6);//测试8,6的最大公约数,默认a>b}

最大公约数和最小公倍数--java实现

代码: //最大公约数 public int gcd(int p,int q){ if(q == 0) return p; return gcd(q, p % q); } //最小公倍数 public int lcm(int p,int q){ int pq = p * q; return pq / gcd(p,q); } 测试: @Test public void go(){ int p = 5,q =17; System.out.println(p+"和"+q+"的最大公

iOS并发编程笔记,包含GCD,Operation Queues,Run Loops,如何在后台绘制UI,后台I/O处理,最佳安全实践避免互斥锁死锁优先级反转等,以及如何使用GCD监视进程文件文件夹,并发测试的方案等

iOS并发编程笔记,包含GCD,Operation Queues,Run Loops,如何在后台绘制UI,后台I/O处理,最佳安全实践避免互斥锁死锁优先级反转等,以及如何使用GCD监视进程文件文件夹,并发测试的方案等 线程 使用Instruments的CPU strategy view查看代码如何在多核CPU中执行.创建线程可以使用POSIX 线程API,或者NSThread(封装POSIX 线程API).下面是并发4个线程在一百万个数字中找最小值和最大值的pthread例子: #import

【poj 2429】GCD &amp; LCM Inverse (Miller-Rabin素数测试和Pollard_Rho_因数分解)

本题涉及的算法个人无法完全理解,在此提供两个比较好的参考. 原理 代码实现 个人改编的AC代码: #include <algorithm> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> using namespace std; #define ll long long int top; const

转 GCD

GCD 深入理解:第一部分 本文翻译自 http://www.raywenderlich.com/60749/grand-central-dispatch-in-depth-part-1 原作者:Derek Selander 译者:@nixzhu 虽然 GCD 已经出现过一段时间了,但不是每个人都明了其主要内容.这是可以理解的:并发一直很棘手,而 GCD 是基于 C 的 API ,它们就像一组尖锐的棱角戳进 Objective-C 的平滑世界.我们将分两个部分的教程来深入学习 GCD . 在这两

HDU 4910 Problem about GCD

Problem about GCD Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 470    Accepted Submission(s): 77 Problem Description Given integer m. Find multiplication of all 1<=a<=m such gcd(a, m)=1 (cop

GCD的个人理解和应用

GCD的个人理解和应用 特点 >>将GCD封装,使我们从繁琐的方法记忆中解脱出来,能够直接快速的应用. 使用方法 1.将工程中的GCD文件中的9个文件拖入自己的工程中(你自己最好建一个文件夹,用来保存这几个文件,方便管理!). 2.在所要用到GCD的view中,导入GCD.h文件 3.封装的GCD文件参见:(https://github.com/YouXianMing/GCD-Program) 源码 1.对GCD封装的源码,在这里下载(https://github.com/YouXianMin