4

下面是我的一些代码,它们在将联系人加载到 tableview 时不会阻塞主线程。它似乎工作正常,但我想知道在 if(accessGranted) 之后调用 dispatch_async 后这是否最终会导致一些不稳定的行为。如果我正在做的是好的做法,那么也许这会对某些人有所帮助,因为我看到很多人对 AB 有很多不同的答案(可能是由于 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];
            });
            });
}
4

0 回答 0