GCD队列操控

队列挂起
dispatch queue可以被挂起和恢复,使用 dispatch_suspend函数来挂起,使用 dispatch_resume 函数来恢复。dispatch source也支持挂起和恢复。注意,dispatch queue挂起时,当前的block会继续执行完,后续的block将不再执行,直至queue被恢复。另外,当销毁已经挂起queue时,需要先恢复queue。

队列目标制定
所有用户队列都有一个目标队列概念。本质上,一个用户队列是不执行任务的,它将任务传递给目标队列执行,通常,目标队列是默认优先级的全局队列。目标队列可以通过函数dispatch_set_target_queue修改,通过只向高优先级的全局队列,可以修改用户队列的优先级。
如果将目标队列指定为main queue,会导致所有提交到用户队列的block在主线程中执行。这样替代在主线程中执行代码的好处在于:用户队列可以单独的被挂起和恢复,还可以重定目标到全局队列,然后所有block会变成全局队列上进行。
如果,将一个用户队列的目标队列指定为另一个用户队列,可以强制两个队列相互协调的串行执行,这样可以作为一个组,通过挂起目标队列,我们可以挂起整个组。

信号量
信号量是一个整形值并且具有一个初始计量值,支持两个操作:信号通知和等待。当一个信号量被一个信号通知,其计数会增加。当一个线程在一个信号量上等待时,线程会被阻塞,直至计数大于零,然后线程会减少这个计数。
可以通过dispatch_semaphore_create函数创建dispatch信号量,使用dispatch_semaphore_signal函数来通知,使用dispatch_semaphore_wait函数来等待。

单次初始化
该特性的主要用途是惰性单例初始化或者其他线程安全数据共享。传统的单里实现为:

+ (instancetype)shareInstance
{
    static SomeObject *object = nil;
    @synchronized ([SomeObject class]) {
        if (!object) {
            object = [[SomeObject alloc] init];
        }
    }
    return object;
}

在GCD中,使用dispatch_once函数实现:

+ (instancetype)shareInstance
{
    static dispatch_once_t pred;
    static SomeObject *object = nil;
    dispatch_once(&pred, ^{
        object = [[SomeObject alloc] init];
    });
    return object;
}

这个稍微比 @synchronized方法简单些,并且GCD确保以更快的方式完成这些检测,它保证block中的代码在任何线程通过 dispatch_once 调用之前被执行,但它不会强制每次调用这个函数都让代码进行同步控制。实际上,如果你去看这个函数所在的头文件,你会发现目前它的实现其实是一个宏,进行了内联的初始化测试,这意味着通常情况下,你不用付出函数调用的负载代价,并且会有更少的同步控制负载。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值