Objective-C Dispatch Queue API

Reference:《Objective-C高级编程》

dispatch_set_target_queue

改变生成的 Dispatch Queue的执行优先级

 dispatch_queue_t mySerialDQ=dispatch_queue_create("mySerialDQ", NULL);
 dispatch_queue_t global_queue_high=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
 dispatch_set_target_queue(mySerialDQ, global_queue_high);
 dispatch_async(mySerialDQ, ^{        
        NSLog(@"hello world.");
    });

防止处理被并行执行(如多个Serial Dispatch Queue会并行执行)

    blk blk1=[self getTask:1];
    blk blk2=[self getTask:2];
    blk blk3=[self getTask:3];
    blk blk4=[self getTask:4];
    dispatch_queue_t mSDQ0 = dispatch_queue_create("mSDQ0",DISPATCH_QUEUE_SERIAL);
    dispatch_queue_t mSDQ1 = dispatch_queue_create("mSDQ1",DISPATCH_QUEUE_SERIAL);
    dispatch_queue_t mSDQ2 = dispatch_queue_create("mSDQ2",DISPATCH_QUEUE_SERIAL);
    dispatch_queue_t mSDQ3 = dispatch_queue_create("mSDQ3",DISPATCH_QUEUE_SERIAL);
    //追加任务到队列
    dispatch_async(mSDQ0, blk1);
    dispatch_async(mSDQ1, blk2);
    dispatch_async(mSDQ2, blk3);
    dispatch_async(mSDQ3, blk4);
 /*输出:多个线程并行执行。
2019-03-14 21:49:58.748918+0800 Block[25562:9113847] 非ui线程1  --><NSThread: 0x600002963300>{number = 3, name = (null)}
2019-03-14 21:49:58.748925+0800 Block[25562:9113848] 非ui线程3  --><NSThread: 0x600002963500>{number = 4, name = (null)}
2019-03-14 21:49:58.748928+0800 Block[25562:9113853] 非ui线程4  --><NSThread: 0x600002961b00>{number = 6, name = (null)}
2019-03-14 21:49:58.748944+0800 Block[25562:9113849] 非ui线程2  --><NSThread: 0x600002966540>{number = 5, name = (null)}
2019-03-14 21:49:59.753133+0800 Block[25562:9113808] ui线程4
2019-03-14 21:49:59.753341+0800 Block[25562:9113808] ui线程2
2019-03-14 21:49:59.753444+0800 Block[25562:9113808] ui线程1
2019-03-14 21:49:59.753562+0800 Block[25562:9113808] ui线程3
    */

//防止处理并行执行,在追加任务前添加:
    dispatch_set_target_queue(mSDQ0, mSDQ3);
    dispatch_set_target_queue(mSDQ1, mSDQ3);
    dispatch_set_target_queue(mSDQ2, mSDQ3);

/*输出:在一个线程中按顺序等待执行
2019-03-14 21:55:42.866039+0800 Block[25608:9116274] 非ui线程1  --><NSThread: 0x6000008026c0>{number = 3, name = (null)}
2019-03-14 21:55:43.869357+0800 Block[25608:9116235] ui线程1
2019-03-14 21:55:43.869388+0800 Block[25608:9116274] 非ui线程2  --><NSThread: 0x6000008026c0>{number = 3, name = (null)}
2019-03-14 21:55:44.870230+0800 Block[25608:9116235] ui线程2
2019-03-14 21:55:44.870267+0800 Block[25608:9116274] 非ui线程3  --><NSThread: 0x6000008026c0>{number = 3, name = (null)}
2019-03-14 21:55:45.875613+0800 Block[25608:9116235] ui线程3
2019-03-14 21:55:45.875634+0800 Block[25608:9116274] 非ui线程4  --><NSThread: 0x6000008026c0>{number = 3, name = (null)}
2019-03-14 21:55:46.881232+0800 Block[25608:9116235] ui线程4
*/

dispatch_after

实现在指定时间后执行某处理
1、3ull*NSEC_PER_SEC:3秒后把任务追加到队列,如果队列中有大量待处理的追加任务时新追加的任务会出现延时。另外RunLoop执行周期也会影响任务执行开始时间。
2、第一个参数dispatch_time_t类型可以由dispatch_time和dispatch_walltime生成
dispatch_time:通常用于计算相对时间
dispatch_walltime:通常用于计算绝对时间

blk blk1=[self getTask:1];
dispatch_queue_t mSDQ0 = dispatch_queue_create("mSDQ0",DISPATCH_QUEUE_SERIAL);
dispatch_time_t dt=dispatch_time(DISPATCH_TIME_NOW, 3ull*NSEC_PER_SEC);
NSLog(@"00");
dispatch_after(dt, mSDQ0, blk1);
NSLog(@"11");
/*输出
2019-03-14 22:05:06.567151+0800 Block[25744:9120715] 00
2019-03-14 22:05:06.567309+0800 Block[25744:9120715] 11
2019-03-14 22:05:09.858652+0800 Block[25744:9120743] 非ui线程1  --><NSThread: 0x600001cb1940>{number = 3, name = (null)}
2019-03-14 22:05:10.859360+0800 Block[25744:9120715] ui线程1
*/
//NSDate 转 dispatch_time_t
-(dispatch_time_t)getDispatchTimeByNSDate:(NSDate *)date
{
    NSTimeInterval interval=[date timeIntervalSince1970];
    double second,subsecond;
    struct timespec time;
    subsecond=modf(interval, &second);
    time.tv_sec=second;
    time.tv_nsec=subsecond*NSEC_PER_SEC;
    dispatch_time_t milestone =dispatch_walltime(&time, 0);
    return  milestone;
}

Dispatch Group

场景:在追加到Dispatch Queue中所有任务都结束后,想执行结束任务。
1、如果只有一个Serial Dispatch Queue,则把结束任务追加到队列最后就行。
2、如果有多个Serial Dispatch Queue或有Concurrent Dispatch Queue时使用
Dispatch Queue可实现。
3、Block通过dispatch_retain 持有Dispatch Group,如果Block执行结束,Block就通过dispatch_release释放持有的Dispatch Group,一旦Dispatch Group使用结束,立即通过dispatch_release函数释放(only for MRC)。

    dispatch_group_t group_t=dispatch_group_create();
    dispatch_group_async(group_t, globalDQ,^{NSLog(@"block1");});
    dispatch_group_async(group_t, globalDQ,^{NSLog(@"block2");});
    dispatch_group_async(group_t, globalDQ,^{NSLog(@"block3");});
    dispatch_group_notify(group_t, globalDQ, ^{
            NSLog(@"....");
        });
/*
2019-03-14 23:08:29.752358+0800 Block[26324:9145484] block1
2019-03-14 23:08:29.752361+0800 Block[26324:9145483] block3
2019-03-14 23:08:29.752358+0800 Block[26324:9145485] block2
2019-03-14 23:08:29.752526+0800 Block[26324:9145484] ....
*/

  • dispatch_group_wait:只要Dispatch Group 的处理未执行完成,就一直等待,中途不可取消。
  • dispatch_group_wait 第二个参数 为 DISPATCH_TIME_FOREVER时返回值恒为0;
  • 一旦调用dispatch_group_wait 函数,”等待“意味着,该函数处于调用状态而不返回;只有在经过指定的等待时间或Dispatch Group中所有任务完成时才返回继续执行调用该函数的线程。
    dispatch_group_t group_t=dispatch_group_create();
    dispatch_group_async(group_t, globalDQ,^{NSLog(@"block1");});
    dispatch_group_async(group_t, globalDQ,^{NSLog(@"block2");});
    dispatch_group_async(group_t, globalDQ,blk1);
    dispatch_time_t dpt=dispatch_time(DISPATCH_TIME_NOW, 1ull*NSEC_PER_SEC);
    NSLog(@"ccc");
    long result= dispatch_group_wait(group_t,dpt);//   等待1s查看是否结束
    NSLog(@"xxxx");
    if(result==0) 
    {
        NSLog(@"finish");
    }
    else{
        NSLog(@"not finish");
    }
//输出:
2019-03-14 23:46:03.362444+0800 Block[26747:9161769] ccc
2019-03-14 23:46:03.362460+0800 Block[26747:9161804] block1
2019-03-14 23:46:03.362448+0800 Block[26747:9161802] block2
2019-03-14 23:46:03.362573+0800 Block[26747:9161803] 非ui线程1  --><NSThread: 0x60000134a780>{number = 3, name = (null)}
2019-03-14 23:46:04.367777+0800 Block[26747:9161769] xxxx
2019-03-14 23:46:04.367962+0800 Block[26747:9161769] finish
2019-03-14 23:46:04.375522+0800 Block[26747:9161769] ui线程1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值