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
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞