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