以下は、連絡先をテーブルビューにロードするときにメインスレッドをブロックしない私のコードの一部です。正常に動作しているように見えますが、if(accessGranted) に続いて dispatch_async が呼び出された後、これが最終的に不規則な動作を引き起こすかどうか疑問に思っています。私がやっていることが良い習慣であるなら、おそらくこれは何人かの人々を助けるでしょう.なぜなら私は多くの人が多くの異なる答えでABについて質問しているのを見てきました.私が間違っていること。
私の理解では、これはすべて同じスレッドで行われているため、スレッドセーフです。
CFErrorRef error = nil;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error);
__block BOOL accessGranted = NO;
if (ABAddressBookRequestAccessWithCompletion != NULL) { // we're on iOS 6 or later
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;
}
if (accessGranted) {
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
CFArrayRef contacts = ABAddressBookCopyArrayOfAllPeople(addressBook);
CFMutableArrayRef peopleMutable = CFArrayCreateMutableCopy(kCFAllocatorDefault,
CFArrayGetCount(contacts),
contacts);
CFArraySortValues(peopleMutable,
CFRangeMake(0, CFArrayGetCount(peopleMutable)),
(CFComparatorFunction) ABPersonComparePeopleByName,
kABPersonSortByFirstName);
CFRelease(contacts);
for (CFIndex i = 0; i < CFArrayGetCount(peopleMutable); i++)
{
ABRecordRef record = CFArrayGetValueAtIndex(peopleMutable, i);
ABMultiValueRef phoneNumberProperty = ABRecordCopyValue(record, kABPersonPhoneProperty);
if (CFBridgingRelease(ABMultiValueCopyValueAtIndex(phoneNumberProperty, 0)) != nil) {
NSString *firstName = CFBridgingRelease(ABRecordCopyValue(record, kABPersonFirstNameProperty));
NSString *lastName = CFBridgingRelease(ABRecordCopyValue(record, kABPersonLastNameProperty));
NSString *phoneNumbers = (__bridge NSString*)ABMultiValueCopyValueAtIndex(phoneNumberProperty, 0);
}
CFRelease(phoneNumberProperty);
}
CFRelease(peopleMutable);
dispatch_async(dispatch_get_main_queue(), ^{
// Update UI
[self.tableView reloadData];
});
});
}