在iOS8中获取联系人列表,使应用程序崩溃
在iOS8(iphone5s)中获取联系人会导致随机崩溃。 坠机详情: 第行:在iOS8中获取联系人列表,使应用程序崩溃,ios,objective-c,ios8,contacts,Ios,Objective C,Ios8,Contacts,在iOS8(iphone5s)中获取联系人会导致随机崩溃。 坠机详情: 第行: ABMultiValueRef multiEmails = ABRecordCopyValue(person, kABPersonEmailProperty); 以下是整个功能: -(NSArray *) getAllContacts { CFErrorRef *error = nil; ABAddressBookRef addressBook = ABAddressBookCreate
ABMultiValueRef multiEmails = ABRecordCopyValue(person, kABPersonEmailProperty);
以下是整个功能:
-(NSArray *) getAllContacts
{
CFErrorRef *error = nil;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, error);
__block BOOL accessGranted = NO;
if (ABAddressBookRequestAccessWithCompletion != NULL) {
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 {
accessGranted = YES;
}
if (accessGranted) {
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, error);
ABRecordRef source = ABAddressBookCopyDefaultSource(addressBook);
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(addressBook, source, kABPersonSortByFirstName);
CFIndex nPeople = ABAddressBookGetPersonCount(addressBook);
NSMutableArray* items = [NSMutableArray arrayWithCapacity:nPeople];
for (int i = 0; i < nPeople; i++)
{
ABRecordRef person = CFArrayGetValueAtIndex(allPeople, i);
//get Contact email
ABMultiValueRef multiEmails = ABRecordCopyValue(person, kABPersonEmailProperty);
for (CFIndex j=0; j<ABMultiValueGetCount(multiEmails); j++) {
CFStringRef contactEmailRef = ABMultiValueCopyValueAtIndex(multiEmails, j);
NSString *contactEmail = (__bridge NSString *)contactEmailRef;
[items addObject:contactEmail];
}
}
return items;
} else {
NSLog(@"Cannot fetch Contacts :( ");
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Fetch failed" message:@"Can't fetch your contacts." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
[alert show];
return nil;
}
}
-(NSArray*)获取所有联系人
{
CFErrorRef*错误=nil;
ABAddressBookRef addressBook=ABAddressBookCreateWithOptions(空,错误);
__block BOOL accessgrated=否;
if(ABAddressBookRequestAccessWithCompletion!=NULL){
dispatch\u semaphore\u t sema=dispatch\u semaphore\u create(0);
ABAddressBookRequestAccessWithCompletion(addressBook,^(已授予bool,CFErrorRef错误){
accessgrated=已授予;
调度信号量信号(sema);
});
调度信号量等待(永远调度时间);
}
否则{
accessgrated=是;
}
如果(已授予访问权限){
ABAddressBookRef addressBook=ABAddressBookCreateWithOptions(空,错误);
ABRecordRef source=ABAddressBookCopyDefaultSource(地址簿);
CFArrayRef allPeople=abAddressBookCopyArrayFallPeopleInSourceWithSortOrdering(addressBook、source、kABPersonSortByFirstName);
CFIndex nppeople=ABAddressBookGetPersonCount(地址簿);
NSMutableArray*items=[NSMutableArray阵列容量:NPEOPE];
for(int i=0;i 对于(CFIndex j=0;j您正在检索ABAddressBookGetPersonCount
(所有源中的所有人员计数,而不仅仅是默认源中的人员计数),并在遍历数组时将其用作上限阈值。但该数组不包含通讯簿中的所有人,而只包含默认源中的人。因此,您可能会超过数组中的项数
我建议使用CFArrayGetCount
而不是ABAddressBookGetPersonCount
您正在检索ABAddressBookGetPersonCount
(所有源中所有人的计数,而不仅仅是默认源中的人数),并在遍历数组时将其用作上限阈值。但该数组不包含通讯簿中的所有人,而只包含默认源中的人。因此,您可能会超过数组中的项数
我建议使用CFArrayGetCount
而不是ABAddressBookGetPersonCount
ABAddressBookCreateWithOptions(NULL,error)
应该是这个吗
CFErrorRef error = NULL;
ABAddressBookCreateWithOptions(NULL, &error);
ABAddressBookCreateWithOptions(空,错误)
应该是这个吗
CFErrorRef error = NULL;
ABAddressBookCreateWithOptions(NULL, &error);
可能是因为无法正确处理内存管理。您没有释放您创建或复制的所有CF对象,并且似乎有许多对象没有释放。您的应用是否可能是由于内存警告而不是崩溃而被终止?崩溃详细信息:EXC\u坏访问内核\u无效\u地址ABRECORDCYVALUE方法的0x000600000000068不是因为这导致了问题,而是因为for
循环都使用变量i
。这通常是有风险的-避免这种情况。您还检索ABAddressBookGetPersonCount
(所有源中所有人员的计数),并将其用作默认源中的人员的索引。还有其他问题(正如insane-36指出的,您没有释放内存;您使用ABAddressBookCreateWithOptions
的错误参数的方式永远不会检索错误对象,如果有,我不会建议使用信号量模型,等等),但索引的潜在不匹配是主要问题。修复了索引,但问题仍然存在。可能是因为无法正确处理内存管理。您没有释放您创建或复制的所有CF对象,并且似乎有许多对象没有被释放。是否有可能t您的应用程序是由于内存警告而不是崩溃而被杀死的吗?崩溃详细信息:EXC_BAD_ACCESS KERN_INVALID_ADDRESS在0x000600000000068处用于ABRecordCopyValue方法不是因为这导致了问题,而是因为for
循环都使用变量i
。这通常是有风险的-避免这种情况。您还在检索ABAddressBookGetPersonCount(所有源中所有人员的计数),并将其用作默认源中人员的索引。还有其他问题(正如insane-36所指出的,您没有释放内存;您使用ABAddressBookCreateWithOptions
的错误参数的方式永远不会检索错误对象(如果有),我不会建议使用信号量模型等。),但索引的潜在不匹配是主要问题。修复了索引,但问题仍然存在。你是对的。我已经使用以下方法修复了它:NSArray allPeoplearray=(\uu-bridge NSArray)allPeople;CFIndex nppeople=allPeoplearray.count;但你的方法更优雅:)我只是使用了核心基础技术,因为您的代码示例是使用核心基础来迭代数组。但是实际上我更喜欢您的方法是好的(虽然我会使用<代码>、SypgigelType < /COD> >或<代码> CFBRGGIGORION ,它将所有权转移到ARC并在数组超出范围时释放它。,然后完全停用CFArray
函数。与电子邮件地址相同,例如NSString*contactEmail=cfbridgengrelease(ABMultiValueCopyValueAtIndex(multiEmails,j));
。你是对的。我已经使用:NSArray allPeoplearray=(\uu bridge NSArray)修复了它所有的人;cFixx nHuff= Apple PrimeRay.Calt;但是你的方式更优雅:我只是使用了核心基础技术,因为你的代码示例使用核心基础来迭代ARR。