On a Stackoverflow question (see "Source 1" at the bottom), I see the following pattern when working with AddressBook in which the programmer wants to block the main thread until the user has granted (or denied) access to his/her AddressBook:
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);
dispatch_release(sema);
}
else { // we're on iOS 5 or older
accessGranted = YES;
}
if (accessGranted) {
NSArray *thePeople = (__bridge_transfer NSArray*)ABAddressBookCopyArrayOfAllPeople(addressBook);
// Do whatever you need with thePeople...
}
but according to the documentation (ABAddressBook Reference), the completion handler is executed on an arbitrary queue, which means it could be executed on the main queue. If the completion handler were placed on the main queue, then the above code would result in a deadlock. Is there any documentation guaranteeing that the completion handler will not be placed on the main queue?
ABAddressBook Reference: "The completion handler is called on an arbitrary queue. If your app uses an address book throughout the app, you are responsible for ensuring that all usage of that address book is dispatched to a single queue to ensure correct thread-safe operation."
Source: