3

这段代码之前已经发布过,并且也被使用过,据我所知。我处于一种情况,我需要代码在我知道我是否可以访问联系人之前不继续。

在 Xcode 5.0.2 和 iOS 6 上,这工作得很好。在 iOS 7 上,它永远挂起,然后当我终止应用程序时,出现对​​话框,要求允许访问联系人。

ABAddressBookRef addressBook = ABAddressBookCreate();

__block BOOL accessGranted = NO;

if (ABAddressBookRequestAccessWithCompletion != NULL) { // we're on iOS 6
dispatch_semaphore_t sema = dispatch_semaphore_create(0);

ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
    accessGranted = granted;
    dispatch_semaphore_signal(sema);
});

    dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); 
}
else { // we're on iOS 5 or older
     accessGranted = YES;
}

在尝试玩这个时,我只需将 BOOL 设置为 NO,然后在块内将其设置为 YES。在块之后,我放了一个 while 循环来检查变量是否为 YES,然后睡了 1 秒钟。在 6 上工作得非常好,在 7 上我永远不会到达块中的 NSLog 语句,并且我永远卡在打印日志语句的 while 循环中。

我在这里做的事情真的很蹩脚吗?还是这种方法在 7 上失控了?

ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error);
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
    if (granted)
    {
        self.myAddressBook = addressBook;
    }

    done = YES;
    NSLog(@"in block, done is %@", done ? @"YES" : @"NO");
    didGrant = granted;

    //dispatch_semaphore_signal(sema);
});

while (!done)
{
    NSLog(@"done is %@", done ? @"YES" : @"NO");
    sleep(1);
}
4

1 回答 1

5

我遇到了同样的问题,我意识到请求访问联系人的对话框无论如何都会阻止应用程序,所以可能存在死锁。所以我只是放弃了信号量并做了这样的事情(在 iOS 7.1.1 上测试并工作):

ABAddressBookRef addressBook = ABAddressBookCreate();

MyController * __weak weakSelf = self;

if (ABAddressBookRequestAccessWithCompletion != NULL)
{ // we're on iOS 6
    if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined)
    {
        ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
            dispatch_async(dispatch_get_main_queue(), ^{
                [weakSelf accessGrantedForAddressBook];
            });
        });    
    }
    else
        if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized); //Maybe add something here to handle kABAuthorizationStatusRestricted
            [self accessGrantedForAddressBook];
    }
}
else // we're on iOS 5 or older
     [self accessGrantedForAddressBook];

这与 Apple 在其文档中所做的非常相似(搜索 ABAddressBookRequestAccessWithCompletion)。此外,ABAddressBookRequestAccessWithCompletion 异步并等待它的意义何在(请参阅此处)..

于 2014-07-04T09:39:13.410 回答