GCD全解析

GCD英文全称:Grand Central Dispatch 翻译就是 宏大的中央调度,是苹果开发的一种支持并行操作的机制,基于C语言,提供了非常多强大的函数

在了解GCD并使用之前,必须要掌握四个名词:串行,并发,同步,异步

串行(Serial):

一个任务执行完, 再执行下一个任务

并发 (Concurrent):

多个任务同时执行(自动开启多个线程),只有在异步函数下才有效

同步(Synchronous):

在当前线程中执行任务,不具备开启新线程的能力

提交的任务在执行完成后才会返回

同步函数: dispatch_sync()

异步 (Asynchronous):

在新的线程中执行任务, 具备开启线程的能力

在新线程中执行任务,具备开启新线程的能力

提交的任务立刻返回,在后台队列中执行

异步函数: dispatch_async()

2.Dispatch Queue

Dispatch Queue是执行处理的等待队列, 按照先进先出(FIFO, First-In-First-Out)的顺序进行任务处理.

开发者将需要执行的任务添加到合适的Dispatch Queue中即可,Dispatch Queue会根据任务添加的顺序先到先执行,其中有以下几种队列:

另外, 队列分两种, 一种是串行队列(Serial Dispatch Queue), 一种是并行队列(Concurrent Dispatch Queue).

//创建一个串行队列

dispatch_queue_tserialQueue=dispatch_queue_create( "com.serial.queue", DISPATCH_QUEUE_SERIAL);

//创建一个并发队列

dispatch_queue_tconcurrentQueue=dispatch_queue_create( "com.concurrent.queue", DISPATCH_QUEUE_CONCURRENT);

//第一个参数为队列名,第二个参数为队列类型,当然,第二个参数人如果写NULL,创建出来的也是一个串行队列。然后我们在异步线程来执行这个队列:

另外系统为我们准备了两个队列

main dispatch queue

功能跟主线程一样,通过dispatch_get_main_queue()来获取,提交到main queue的任务实际上都是在主线程执行的,所以这是一个串行队列

dispatch_queue_tqueue= dispatch_get_main_queue();

global dispatch queues

系统给每个应用提供四个全局的并发队列,这四个队列分别有不同的优先级:高、默认、低以及后台,用户不能去创建全局队列,只能根据优先级去获取:

dispatch_queue_tqueue= dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

3.dispatch_sync&dispatch_async

执行队列中任务的两种方式,dispatch_sync是同步任务,dispatch_async是异步任务

1.用同步的方式执行任务(同步:synchronization), 只能在当前线程中执行任务,不具备开启新线程的能力

/*

  • 第一个参数:该任务所在的队列

  • 第二个参数:该任务要做的事情

*/

dispatch_sync( dispatch_queue_tqueue, dispatch_block_tblock);

假如我指定的队列A是串行队列,则该队列中只能有一个线程,也就是说我放在队列A中的任务,所以必须得一个一个的执行。不仅如此,在上面我们还手动选择了在队列A中用同步的方式执行任务,这也限制了,队列中的任务只能一个一个执行。

假如我指定的队列A是并行队列,则该队列中可以开辟多个线程去执行任务,虽然如此,但由于我们在上面手动选择了在队列A中用同步的方式执行线程,所以队列A中的任务也只能一个一个去执行,不能开辟多线程同时执行。

2.用异步的方式执行任务(异步:asynchronous),可以在新的线程中执行任务,具备开启新线程的能力。

dispatch_async( dispatch_queue_tqueue, dispatch_block_tblock);

假如此时我指定的队列B是并行队列,则表明该队列中可以存在多个线程,又因为我们采用的是异步的方式执行任务,所以在这个队列的任务可以实现同时运行。

假如此时我指定的队列B是串行队列,则表明该队列中,只能有一个线程,所以尽管我采用异步的方式执行任务,但该队列中的任务还是只能一个一个的运行。

4.创建的线程任务有四种执行方式

1. 串行队列同步执行任务

同步不具有开辟新线程的能力,不会开辟新的线程去执行任务,会在当前程序的主线程中执行任务。

按照串行的方式去执行任务

-( void)syncSERIAL{

NSLog( @"star");

//不会开辟新的线程

dispatch_queue_tqueue=dispatch_queue_create( "com.GCD_demo.www", DISPATCH_QUEUE_SERIAL);

dispatch_sync(queue, ^{

NSLog( @"SERIAL_work_1 ");

});

dispatch_sync(queue, ^{

NSLog( @"SERIAL_work_2 ");

});

dispatch_sync(queue, ^{

NSLog( @"SERIAL_work_3 ");

});

NSLog( @"end");

}

执行结果

2016 -07-2020 :08:09.695GCD_Demo[8196:1029563]star

2016 -07-2020 :08:09.696GCD_Demo[8196:1029563]SERIAL_work_1

2016 -07-2020 :08:09.696GCD_Demo[8196:1029563]SERIAL_work_2

2016 -07-2020 :08:09.696GCD_Demo[8196:1029563]SERIAL_work_3

2016 -07-2020 :08:09.696GCD_Demo[8196:1029563]end

由于是同步操作,不能开辟线程,所以都是在主线程并按照顺序执行

2. 串行队列异步执行任务

异步具有创建新线程的能力,会开辟新的线程去执行任务

按照串行的方式去执行任务

-( void)asyncSERIAL{

NSLog( @"star");

//会开辟新的线程,但是是串行执行任务

dispatch_queue_tqueue=dispatch_queue_create( "ki", DISPATCH_QUEUE_SERIAL);

dispatch_async(queue, ^{

[ NSThreadsleepForTimeInterval: 3];

NSLog( @"SERIAL_work_1 ");

});

dispatch_async(queue, ^{

[ NSThreadsleepForTimeInterval: 2];

NSLog( @"SERIAL_work_2 ");

});

dispatch_async(queue, ^{

NSLog( @"SERIAL_work_3 ");

});

NSLog( @"end");

}

执行结果

2016 -07-2020 :09:58.494GCD_Demo[8213:1031268]star

2016 -07-2020 :09:58.495GCD_Demo[8213:1031268]end

2016 -07-2020 :10:01.496GCD_Demo[8213:1031315]SERIAL_work_1

2016 -07-2020 :10:03.502GCD_Demo[8213:1031315]SERIAL_work_2

2016 -07-2020 :10:03.502GCD_Demo[8213:1031315]SERIAL_work_3

因为是异步操作,所以有个编号为2的子线程被开辟,但有因为是串行队列,所以只开辟了一个线程。最终造就了三个任务顺序执行。

3. 并行队列同步执行任务

同步不具有创建新线程的能力,不会开辟新的线程去执行任务,会在当前程序的主线程去执行任务

按照同步的方式去执行任务

-( void)syncCONCURRENT{

NSLog( @"star");

//不会开辟新的线程

//串行执行命令

dispatch_queue_tqueue=dispatch_queue_create( "com.GCD_demo.www", DISPATCH_QUEUE_CONCURRENT);

dispatch_sync(queue, ^{

[ NSThreadsleepForTimeInterval: 3];

NSLog( @"CONCURRENT_work_1 ");

});

dispatch_sync(queue, ^{

[ NSThreadsleepForTimeInterval: 2];

NSLog( @"CONCURRENT_work_2 ");

});

dispatch_sync(queue, ^{

NSLog( @"CONCURRENT_work_3 ");

});

NSLog( @"end");

}

执行结果

-( void)syncCONCURRENT{

NSLog( @"star");

//不会开辟新的线程

//串行执行命令

dispatch_queue_tqueue=dispatch_queue_create( "com.GCD_demo.www", DISPATCH_QUEUE_CONCURRENT);

dispatch_sync(queue, ^{

[ NSThreadsleepForTimeInterval: 3];

NSLog( @"CONCURRENT_work_1 ");

});

dispatch_sync(queue, ^{

[ NSThreadsleepForTimeInterval: 2];

NSLog( @"CONCURRENT_work_2 ");

});

dispatch_sync(queue, ^{

NSLog( @"CONCURRENT_work_3 ");

});

NSLog( @"end");

}

虽然并行队列决定了该队列中可以有多个线程,但由于是同步操作,不能开辟线程,所以还都是在主线程中按顺序执行。

4. 并发队列异步执行任务(常用)

异步具有创建新线程的能力,会开辟新的线程去执行任务,不会在当前程序的主线程去执行任务

按照并发的方式去执行任务

-( void)asyncCONCURRENT{

NSLog( @"star");

//一个队列 为 每个任务开辟一个线程

dispatch_queue_tqueue=dispatch_queue_create( "com.GCD_demo.www", DISPATCH_QUEUE_CONCURRENT);

dispatch_async(queue, ^{

[ NSThreadsleepForTimeInterval: 3];

NSLog( @"CONCURRENT_work_1 ");

});

dispatch_async(queue, ^{

[ NSThreadsleepForTimeInterval: 2];

NSLog( @"CONCURRENT_work_2 ");

});

dispatch_async(queue, ^{

NSLog( @"CONCURRENT_work_3 ");

});

NSLog( @"end");

}

执行结果

2016 -07-2020 :18:26.768GCD_Demo[8256:1038143]star

2016 -07-2020 :18:26.768GCD_Demo[8256:1038143]end

2016 -07-2020 :18:26.769GCD_Demo[8256:1038192]CONCURRENT_work_3

2016 -07-2020 :18:28.771GCD_Demo[8256:1038179]CONCURRENT_work_2

2016 -07-2020 :18:29.773GCD_Demo[8256:1038188]CONCURRENT_work_1

并行队列可以里可以有多个线程,同步执行的方式又可以开辟多个线程,所以这里实现了多个线程并行执行。

5.Dispatch Group

当我们想在gcd queue中所有的任务执行完毕之后做些特定事情的时候,也就是队列的同步问题,如果队列是串行的话,那将该操作最后添加到队列中即可,但如果队列是并行队列的话,这时候就可以利用dispatch_group来实现了,dispatch_group能很方便的解决同步的问题。dispatch_group_create可以创建一个group对象,然后可以添加block到该组里面,下面看下它的一些用法:

dispatch_group_notify

是通过异步的方式通知,所以,不会阻塞线程

-( void)asyncGroupNotify

{

NSLog( @"star");

dispatch_group_t group=dispatch_group_create();

dispatch_queue_tqueue=dispatch_queue_create( "com.GCD_demo.www", DISPATCH_QUEUE_CONCURRENT);

dispatch_group_async(group, queue, ^{

[ NSThreadsleepForTimeInterval: 1];

NSLog( @"group_work_1");

});

dispatch_group_async(group, queue, ^{

[ NSThreadsleepForTimeInterval: 6];

NSLog( @"group_work_2");

});

dispatch_group_async(group, queue, ^{

[ NSThreadsleepForTimeInterval: 2];

NSLog( @"group_work_3");

});

dispatch_group_notify(group, queue, ^{

NSLog( @"dispatch_group_Notify 结束");

});

}

运行结果

2016 -07-2113 :51:40.600GCD_Demo[9044:1162213]star

2016 -07-2113 :51:41.605GCD_Demo[9044:1162359]group_work_1

2016 -07-2113 :51:42.608GCD_Demo[9044:1162389]group_work_3

2016 -07-2113 :51:46.603GCD_Demo[9044:1162349]group_work_2

2016 -07-2113 :51:46.605GCD_Demo[9044:1162349]dispatch_group_Notify结束

dispatch_group_wait

会阻塞当前线程,知道任务都完成时才会继续执行下面的代码

-( void)asyncGroupWait

{

NSLog( @"star");

dispatch_group_t group=dispatch_group_create();

dispatch_queue_tqueue=dispatch_queue_create( "com.GCD_demo.www", DISPATCH_QUEUE_CONCURRENT);

dispatch_group_async(group, queue, ^{

[ NSThreadsleepForTimeInterval: 1];

NSLog( @"group_work_1");

});

dispatch_group_async(group, queue, ^{

[ NSThreadsleepForTimeInterval: 6];

NSLog( @"group_work_2");

});

dispatch_group_async(group, queue, ^{

[ NSThreadsleepForTimeInterval: 2];

NSLog( @"group_work_3");

});

//在此设置了一个12秒的等待时间,如果group的执行结束没有到12秒那么就返回0

//如果执行group的执行时间超过了12秒,那么返回非0 数值,

//在使用dispatch_group_wait函数的时候,会阻塞当前线程,阻塞的时间 在wait函数时间值和当前group执行时间值取最小的。

longkk=dispatch_group_wait(group, dispatch_time(DISPATCH_TIME_NOW, 12* NSEC_PER_SEC));

if(kk== 0)

{

NSLog( @"dispatch_group_wait 结果1");

}

else

{

NSLog( @"dispatch_group_wait 结果2");

}

}

执行结果

2016 -07-2113 :56:47.471GCD_Demo[9065:1165380]star

2016 -07-2113 :56:48.472GCD_Demo[9065:1165494]group_work_1

2016 -07-2113 :56:49.476GCD_Demo[9065:1165502]group_work_3

2016 -07-2113 :56:53.475GCD_Demo[9065:1165485]group_work_2

2016 -07-2113 :56:53.475GCD_Demo[9065:1165380]dispatch_group_wait结果1

dispatch_group_enter&dispatch_group_leave

假如我们不想使用dispatch_group_async异步的将任务丢到group中去执行,这时候就需要用到dispatch_group_enter跟dispatch_group_leave方法,这两个方法要配对出现,以下这两种方法是等价的:

-( void)asyncGroupEnter

{

// 群组-统一监控一组任务

dispatch_group_t group = dispatch_group_create();

dispatch_queue_tqueue = dispatch_get_global_queue( 0, 0);

// 1> 入组 -> 之后的 block 会被 group 监听

// dispatch_group_enter 一定和 dispatch_group_leave 要配对出现

dispatch_group_enter(group);

dispatch_async(queue, ^{

NSLog( @"dispatch_async_work1");

// block 的末尾,所有任务执行完毕后,添加一个出组

dispatch_group_leave(group);

});

// 再次入组

dispatch_group_enter(group);

dispatch_async(queue, ^{

[ NSThreadsleepForTimeInterval: 6];

NSLog( @"dispatch_async_work1");

// block 的末尾,所有任务执行完毕后,添加一个出组

dispatch_group_leave(group);

});

// 群组结束

dispatch_group_notify(group, dispatch_get_main_queue(), ^{

NSLog( @"OVER");

});

NSLog( @"come here");

}

执行结果

2016 -07-2115 :21:40.707GCD_Demo[9256:1205427]comehere

2016 -07-2115 :21:40.707GCD_Demo[9256:1205465]dispatch_async_work1

2016 -07-2115 :21:46.709GCD_Demo[9256:1205460]dispatch_async_work1

2016 -07-2115 :21:46.710GCD_Demo[9256:1205427]OVER

6. Dispatch Block

添加到gcd队列中执行的任务是以block的形式添加的,block封装了需要执行功能,block带来的开发效率提升就不说了,gcd跟block可以说是一对好基友,能够很好的配合使用。

-( void)dispatchBlock

{

dispatch_queue_tqueue= dispatch_queue_create( "com.GCD_demo.www", DISPATCH_QUEUE_SERIAL);

dispatch_block_tblock=dispatch_block_create( 0, ^{

NSLog(@ "dispatchBlock_work");

});

dispatch_sync( queue, block);

}

** 1.dispatch_block_wait**

当需要等待前面的任务执行完毕时,我们可以使用dispatch_block_wait这个接口,设置等待时间DISPATCH_TIME_FOREVER会一直等待直到前面的任务完成.用法跟dispatch_group_wait类似

-( void)dispatchBlockWait

{

dispatch_queue_tqueue = dispatch_queue_create( "com.GCD_demo.www", DISPATCH_QUEUE_SERIAL);

dispatch_block_t block = dispatch_block_create( 0, ^{

NSLog( @"before sleep");

[ NSThreadsleepForTimeInterval: 6];

NSLog( @"after sleep");

});

dispatch_async(queue, block);

//等待前面的任务执行完毕

longkk=dispatch_block_wait(block, dispatch_time(DISPATCH_TIME_NOW, 3* NSEC_PER_SEC));

if(kk== 0)

{

NSLog( @"coutinue");

}

else

{

NSLog( @"timeOut!!!");

}

}

执行结果

2016 -07-2116 :28:38.313GCD_Demo[9533:1251011]beforesleep

2016 -07-2116 :28:41.314GCD_Demo[9533:1250971]timeOut!!!

2016 -07-2116 :28:44.318GCD_Demo[9533:1251011]aftersleep

** 2.dispatch_block_notify**

dispatch_block_notify当观察的某个block执行结束之后立刻通知提交另一特定的block到指定的queue中执行,该函数有三个参数,第一参数是需要观察的block,第二个参数是被通知block提交执行的queue,第三参数是当需要被通知执行的block

-( void)dispatchBlockNotify

{

dispatch_queue_tqueue = dispatch_queue_create( "com.GCD_demo.www", DISPATCH_QUEUE_SERIAL);

dispatch_block_t previousBlock = dispatch_block_create( 0, ^{

NSLog( @"previousBlock begin");

[ NSThreadsleepForTimeInterval: 2];

NSLog( @"previousBlock done");

});

dispatch_async(queue, previousBlock);

dispatch_block_t notifyBlock = dispatch_block_create( 0, ^{

NSLog( @"notifyBlock");

});

//当previousBlock执行完毕后,提交notifyBlock到global queue中执行

dispatch_block_notify(previousBlock, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), notifyBlock);

}

执行结果

2016 -07-2116 :38:19.756GCD_Demo[9664:1261328]previousBlockbegin

2016 -07-2116 :38:21.762GCD_Demo[9664:1261328]previousBlockdone

2016 -07-2116 :38:21.762GCD_Demo[9664:1261329]notifyBlock

3. dispatch_block_cancel

可以取消提交到队列的block

-( void)dispatchBlockCancel

{

dispatch_queue_tqueue = dispatch_queue_create( "com.GCD_demo.www", DISPATCH_QUEUE_CONCURRENT);

dispatch_block_t block1 = dispatch_block_create( 0, ^{

NSLog( @"block1 begin");

[ NSThreadsleepForTimeInterval: 1];

NSLog( @"block1 done");

});

dispatch_block_t block2 = dispatch_block_create( 0, ^{

NSLog( @"block2 ");

});

dispatch_async(queue, block1);

dispatch_async(queue, block2);

dispatch_block_cancel(block2);

}

执行结果

2016 -07-2116 :50:28.140GCD_Demo[9723:1272259]block1begin

2016 -07-2116 :50:29.144GCD_Demo[9723:1272259]block1done

7.dispatch_after

来延迟执行的GCD方法,因为在主线程中我们不能用sleep来延迟方法的调用,所以用它是最合适的,我们做一个简单的例子:

-( void)dispatchAfter

{

NSLog( @"dispatchAfter_star");

int64_t time= 2* NSEC_PER_SEC;

dispatch_queue_tmainQueue=dispatch_get_main_queue();

for( inti= 0; i< 5; i++) {

dispatch_time_t disTime=dispatch_time(DISPATCH_TIME_NOW, time*i);

dispatch_after(disTime, mainQueue, ^{

NSLog( @"dispatchAfter_work");

});

}

}

执行结果

2016 -07-2116 :12:07.204GCD_Demo[9439:1237251]dispatchAfter_star

2016 -07-2116 :12:07.211GCD_Demo[9439:1237251]dispatchAfter_work

2016 -07-2116 :12:09.398GCD_Demo[9439:1237251]dispatchAfter_work

2016 -07-2116 :12:11.205GCD_Demo[9439:1237251]dispatchAfter_work

2016 -07-2116 :12:13.205GCD_Demo[9439:1237251]dispatchAfter_work

2016 -07-2116 :12:15.205GCD_Demo[9439:1237251]dispatchAfter_work

8.dispatch_apply

dispatch_apply类似一个for循环,会在指定的dispatch queue中运行block任务n次,如果队列是并发队列,则会并发执行block任务,dispatch_apply是一个同步调用,block任务执行n次后才返回。

-( void)dispatchApply

{

dispatch_queue_tqueue= dispatch_queue_create( "com.GCD_demo.www", DISPATCH_QUEUE_CONCURRENT);

dispatch_apply( 6, queue, ^( size_ti) {

NSLog(@ "do a job %zu times",i);

});

NSLog(@ "go on");

}

执行结果

2016 -07-2117 :04:54.558GCD_Demo[9831:1284549]doajob0 times

2016 -07-2117 :04:54.564GCD_Demo[9831:1284583]doajob1 times

2016 -07-2117 :04:54.564GCD_Demo[9831:1284589]doajob2 times

2016 -07-2117 :04:54.564GCD_Demo[9831:1284593]doajob3 times

2016 -07-2117 :04:54.564GCD_Demo[9831:1284549]doajob4 times

2016 -07-2117 :04:54.564GCD_Demo[9831:1284583]doajob5 times

2016 -07-2117 :04:54.566GCD_Demo[9831:1284549]goon

9.dispatch_once

整个程序运行中只会执行一次,使用dispatch_once可以简化代码并且彻底保证线程安全,开发者根本无须担心加锁或者同步。所有问题都由GCD在底层处理。由于每次调用时都必须使用完全相同的标记,所以标记要声明成static。所以用在单例模式上是最好的

s

taticSingletonTimer * instance;

staticdispatch_once_tonceToken;

dispatch_once(&onceToken, ^{

instance = [[SingletonTimer alloc] init];

});

returninstance;

10. dispatch_barrier_async

dispatch_barrier_async用于等待前面的任务执行完毕后自己才执行,而它后面的任务需等待它完成之后才执行。一个典型的例子就是数据的读写,通常为了防止文件读写导致冲突,我们会创建一个串行的队列,所有的文件操作都是通过这个队列来执行,比如FMDB,这样就可以避免读写冲突。不过其实这样效率是有提升的空间的,当没有更新数据时,读操作其实是可以并行进行的,而写操作需要串行的执行

-( void)diapatchBarrier

{

dispatch_queue_tqueue = dispatch_queue_create( "com.GCD_demo.www", DISPATCH_QUEUE_CONCURRENT);

dispatch_async(queue, ^{

[ NSThreadsleepForTimeInterval: 6];

NSLog( @"dispatch_async_work1");

});

dispatch_async(queue, ^{

[ NSThreadsleepForTimeInterval: 2];

NSLog( @"dispatch_async_work2");

});

dispatch_barrier_async(queue, ^{

NSLog( @"dispatch_async_work3");

[ NSThreadsleepForTimeInterval: 1];

});

dispatch_async(queue, ^{

[ NSThreadsleepForTimeInterval: 1];

NSLog( @"dispatch_async_work4");

});

}

执行结果

2016 -07-2115 :54:24.402GCD_Demo[9354:1225160]dispatch_async_work2

2016 -07-2115 :54:28.403GCD_Demo[9354:1225152]dispatch_async_work1

2016 -07-2115 :54:28.403GCD_Demo[9354:1225152]dispatch_async_work3

2016 -07-2115 :54:30.412GCD_Demo[9354:1225152]dispatch_async_work4

11.dispatch_set_target_queue

1.系统的Global Queue是可以指定优先级的,那我们可以用到dispatch_set_target_queue这个方法来指定自己创建队列的优先级

-( void)DispatchSet

{

dispatch_queue_tserialDiapatchQueue=dispatch_queue_create( "com.GCD_demo.www", DISPATCH_QUEUE_SERIAL);

dispatch_queue_tdispatchgetglobalqueue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);

dispatch_set_target_queue(serialDiapatchQueue, dispatchgetglobalqueue);

dispatch_async(serialDiapatchQueue, ^{

NSLog( @"我优先级低,先让让");

});

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

NSLog( @"我优先级高,我先block");

});

}

执行结果

2016 -07-2117 :22:02.512GCD_Demo[9902:1297023]我优先级高,我先 block

2016 -07-2117 :22:02.512GCD_Demo[9902:1297035]我优先级低,先让让

2.dispatch_set_target_queue除了能用来设置队列的优先级之外,还能够创建队列的层次体系,当我们想让不同队列中的任务同步的执行时,我们可以创建一个串行队列,然后将这些队列的target指向新创建的队列即可

-( void)dispatchSet2

{

dispatch_queue_ttargetQueue = dispatch_queue_create( "target_queue", DISPATCH_QUEUE_SERIAL);

dispatch_queue_tqueue1 = dispatch_queue_create( "queue1", DISPATCH_QUEUE_SERIAL);

dispatch_queue_tqueue2 = dispatch_queue_create( "queue2", DISPATCH_QUEUE_CONCURRENT);

dispatch_set_target_queue(queue1, targetQueue);

dispatch_set_target_queue(queue2, targetQueue);

dispatch_async(queue1, ^{

[ NSThreadsleepForTimeInterval: 3.f];

NSLog( @"do job1");

});

dispatch_async(queue2, ^{

[ NSThreadsleepForTimeInterval: 2.f];

NSLog( @"do job2");

});

dispatch_async(queue2, ^{

[ NSThreadsleepForTimeInterval: 1.f];

NSLog( @"do job3");

});

}

执行结果

2016 -07-2117 :28:54.327GCD_Demo[10043:1303853]dojob1

2016 -07-2117 :28:56.331GCD_Demo[10043:1303853]dojob2

2016 -07-2117 :28:57.335GCD_Demo[10043:1303853]dojob3
  • 11
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值