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 中声明这些对象只能在一个线程上创建和使用。您的代码似乎在原始线程上创建了 ABAddressBook
和 AVRecordRefs
,然后从 dispatch_async
块访问它们。我建议寻找另一种方法来执行此操作,在后台线程上创建 ABAddressBook
和 AVRecordRefs
"just in time"。
Another question 还有一些更相关的信息...
我在获取随机人员变量的生日或电子邮件时遇到 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 中声明这些对象只能在一个线程上创建和使用。您的代码似乎在原始线程上创建了 ABAddressBook
和 AVRecordRefs
,然后从 dispatch_async
块访问它们。我建议寻找另一种方法来执行此操作,在后台线程上创建 ABAddressBook
和 AVRecordRefs
"just in time"。
Another question 还有一些更相关的信息...