ABRecordCopyValue 中的 EXC 错误访问

EXC BAD ACCESS in ABRecordCopyValue

我在获取随机人员变量的生日或电子邮件时遇到 EXC_BAD_ACCESS 问题。我尝试使用以下代码,当我使用 dispatch_async.

运行 时失败了
ABAddressBook addressBook = ABAddressBookCreateWithOptions(NULL, error);

CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook);
CFIndex nPeople = ABAddressBookGetPersonCount(addressBook);
int maxThreads = 8;
int chunkSize = (int)(nPeople/maxThreads);

for (int loopNum = 0; loopNum < maxThreads; loopNum++)
{
    int initCondition = chunkSize*loopNum;
    int termCondition = (loopNum==(maxThreads-1)) ? (int)nPeople : chunkSize*(loopNum+1);

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        for (int i=initCondition; i<termCondition; i++)
        {
            @try {
                ABRecordRef person = CFArrayGetValueAtIndex(allPeople, i);

                NSString *firstName = (__bridge NSString *)(ABRecordCopyValue(person, kABPersonFirstNameProperty)) ? (__bridge NSString *)(ABRecordCopyValue(person, kABPersonFirstNameProperty)) : @"";
                NSString *lastName = (__bridge NSString *)(ABRecordCopyValue(person, kABPersonLastNameProperty)) ? (__bridge NSString *)(ABRecordCopyValue(person, kABPersonLastNameProperty)) :@"";

                NSString *birthDate = (__bridge NSString *)(ABRecordCopyValue(person, kABPersonBirthdayProperty));

                ABMultiValueRef emailMultiValue = ABRecordCopyValue(person, kABPersonEmailProperty);
                NSArray *emailAddresses = (__bridge NSArray *)ABMultiValueCopyArrayOfAllValues(emailMultiValue);

                ABMultiValueRef phoneNumbers = ABRecordCopyValue(person, kABPersonPhoneProperty);

                NSMutableArray *numbers = [NSMutableArray arrayWithCapacity:ABMultiValueGetCount(phoneNumbers)];
                for (CFIndex i = 0; i < ABMultiValueGetCount(phoneNumbers); i++)
                {
                    NSString *phoneNumber = (__bridge_transfer NSString *) ABMultiValueCopyValueAtIndex(phoneNumbers, i);
                    phoneNumber = [self removeSpecialChars:phoneNumber];
                    if ([phoneNumber length] >= 8)
                    {
                        NSString *mobileNumber = [self getPhoneNuber:phoneNumber];;
                        if ([mobileNumber length] > 7 && [mobileNumber length] < 11)
                            [numbers addObject:mobileNumber];
                    }
                }
                NSString *mobileNumbers = [numbers componentsJoinedByString:@","];
            }
            @catch (NSException *exception)
            {
                NSLog(@"%@", exception);
            }
        }
    });
}

当我 运行 没有 dispatch_async 块的代码时,它 运行 没有错误。我想用 dispatch_async 块来并行扫描地址簿并检测本地数据库的任何更改。

documentation for ABAddressBookRef 中声明这些对象只能在一个线程上创建和使用。您的代码似乎在原始线程上创建了 ABAddressBookAVRecordRefs,然后从 dispatch_async 块访问它们。我建议寻找另一种方法来执行此操作,在后台线程上创建 ABAddressBookAVRecordRefs "just in time"。

Another question 还有一些更相关的信息...