このコードは以前に投稿されており、私が収集したものからも使用されています。連絡先にアクセスできるかどうかがわかるまで、コードを続行しないようにする必要がある状況にあります。
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に設定するだけです。ブロックの後、変数がYESであることを確認するwhileループを配置し、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);
}