iOS dispatch信号量semaphore

在iOS中,dispatch队列可以实现类似java的Notify/Wait机制来保证线程同步。

 

1.创建信号量,参数是0,用来指示需不需要等待

dispatch_semaphore_t sema=dispatch_semaphore_create(0);

2.等待信号量,信号量如果大于等于0,则表示等待,这里设置超时时间DISPATCH_TIME_FOREVER表示永久等待

dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);

3.使用信号量

dispatch_semaphore_t sema=dispatch_semaphore_create(0); 
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            // 耗时的操作
      dispatch_semaphore_signal(sema); //让sema变量减1
 });

dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);

注:上面就完成了简单的同步,当然,你还可以设计出更复杂的程序,比如《消费者与生产者的关系》

 

举一个常用的例子,获取联系人权限

 

+(NSString *)getContacts{
    
//获取通讯录权限
ABAuthorizationStatus authStatus = ABAddressBookGetAuthorizationStatus();
if(authStatus!=kABAuthorizationStatusAuthorized)
{
    //是否有通讯录权限
    __block BOOL accessGranted = NO;

    ABAddressBookRef tmpAddressBook = ABAddressBookCreateWithOptions(NULL, NULL);
    dispatch_semaphore_t sema=dispatch_semaphore_create(0);
    ABAddressBookRequestAccessWithCompletion(tmpAddressBook, ^(bool greanted, CFErrorRef error){
        accessGranted = greanted;
        dispatch_semaphore_signal(sema);
        
    });
    
    dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);

    if(accessGranted == NO){
        
        return @"[]";
    }
}

 //读取联系人----------此处省略联系人读取步骤-------------------
}

注意:dispatch_semaphore_signal(sema)该函数必须在设置被设置变量的后面

accessGranted = greanted;
dispatch_semaphore_signal(sema);

如果顺序出现问题,那么aceesGranted的值将永远是NO,因为dispatch_semaphore_signal改变sema后会立即让dispatch_semaphore_wait是否继续等待,如果不需要,则后续代码立即执行,从而造成执行下面的语句,返回 "[]"

if(accessGranted == NO){
        
        return @"[]";
}

 

转载于:https://my.oschina.net/ososchina/blog/700523

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值