2

在 Stackoverflow 问题上(请参阅底部的“源 1”),我在使用 AddressBook 时看到以下模式,其中程序员希望阻止主线程,直到用户授予(或拒绝)访问他/她的 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...

}

但根据文档(ABAAddressBook Reference),完成处理程序在任意队列上执行,这意味着它可以在主队列上执行。如果完成处理程序放在主队列上,那么上面的代码将导致死锁。是否有任何文档保证完成处理程序不会放在主队列中?

ABAddressBook 参考:“在任意队列上调用完成处理程序。如果您的应用程序在整个应用程序中使用地址簿,您有责任确保将该地址簿的所有使用分派到单个队列,以确保正确的线程安全操作。”

资源:

  1. 第一个答案:如何在 iOS 6 中正确使用 ABAddressBookCreateWithOptions 方法?
4

0 回答 0