iPhone SDK:带CFRelease的EXC_BAD_ACCESS用于ABAddressBookRef
问题描述:
我的代码有非常奇怪的错误..实际上,根本没有错误,只是调试器以“程序接收到的信号:”EXC_BAD_ACCESS“”消息开始。 任何人都可以帮助我吗?我非常困惑......谢谢。iPhone SDK:带CFRelease的EXC_BAD_ACCESS用于ABAddressBookRef
-(NSString *)fullNameForPhone:(NSString *)ph withAlternativeText:(NSString *)text
{
ABAddressBookRef addressBookRef = ABAddressBookCreate();
NSLog(@"create addressBookRef");
NSString *stringToReturn = text;
CFArrayRef allPeopleRef = ABAddressBookCopyArrayOfAllPeople(addressBookRef);
NSLog(@"create allPeopleRef");
CFIndex nPeople = ABAddressBookGetPersonCount(addressBookRef);
int i = 0;
BOOL nameFound = NO;
while ((i < nPeople) && (!nameFound))
{
ABRecordRef recordRef = CFArrayGetValueAtIndex(allPeopleRef, i);
NSLog(@" create recordRef");
CFStringRef allRecordPhonesRef = ABRecordCopyValue(recordRef, kABPersonPhoneProperty);
NSLog(@" create allRecordPhonesRef");
CFIndex nPhones = ABMultiValueGetCount(allRecordPhonesRef);
int currentPhone = 0;
for (currentPhone = 0; currentPhone < nPhones; currentPhone++)
{
CFStringRef currentPhoneNumberRef = ABMultiValueCopyValueAtIndex(allRecordPhonesRef, currentPhone);
NSLog(@" create currentPhoneNumberRef");
NSString *currentCleanPhoneNumber = [self cleanPhoneNumberForString:[NSString stringWithFormat:@"%@", currentPhoneNumberRef]];
if (currentPhoneNumberRef!=NULL)
{
NSLog(@" release currentPhoneNumberRef");
CFRelease(currentPhoneNumberRef);
}
if ([ph isEqualToString:currentCleanPhoneNumber])
{
CFStringRef firstName = ABRecordCopyValue(recordRef, kABPersonFirstNameProperty);
CFStringRef lastName = ABRecordCopyValue(recordRef, kABPersonLastNameProperty);
NSString *fullName = [self fullNameForFirstName:[NSString stringWithFormat:@"%@", firstName]
andLastName:[NSString stringWithFormat:@"%@", lastName]];
if (firstName != NULL)
CFRelease(firstName);
if (lastName != NULL)
CFRelease(lastName);
stringToReturn = fullName;
nameFound = YES;
break;
}
}
CFRelease(allRecordPhonesRef);
NSLog(@" release allRecordPhonesRef");
CFRelease(recordRef);
NSLog(@" release recordRef");
i++;
}
CFRelease(allPeopleRef);
NSLog(@"release allPeopleRef");
CFRelease(addressBookRef);
NSLog(@"release addressBookRef");
return stringToReturn;
}
控制台输出是:
2009-07-31 00:20:05.230 abmodular[21747:20b] create addressBookRef
2009-07-31 00:20:05.231 abmodular[21747:20b] create allPeopleRef
2009-07-31 00:20:05.231 abmodular[21747:20b] create recordRef
2009-07-31 00:20:05.232 abmodular[21747:20b] create allRecordPhonesRef
2009-07-31 00:20:05.232 abmodular[21747:20b] create currentPhoneNumberRef
2009-07-31 00:20:05.232 abmodular[21747:20b] release currentPhoneNumberRef
2009-07-31 00:20:05.232 abmodular[21747:20b] create currentPhoneNumberRef
2009-07-31 00:20:05.233 abmodular[21747:20b] release currentPhoneNumberRef
2009-07-31 00:20:05.233 abmodular[21747:20b] release allRecordPhonesRef
2009-07-31 00:20:05.233 abmodular[21747:20b] release recordRef
2009-07-31 00:20:05.233 abmodular[21747:20b] create recordRef
2009-07-31 00:20:05.234 abmodular[21747:20b] create allRecordPhonesRef
2009-07-31 00:20:05.234 abmodular[21747:20b] create currentPhoneNumberRef
2009-07-31 00:20:05.234 abmodular[21747:20b] release currentPhoneNumberRef
2009-07-31 00:20:05.234 abmodular[21747:20b] release allRecordPhonesRef
2009-07-31 00:20:05.235 abmodular[21747:20b] release recordRef
2009-07-31 00:20:05.235 abmodular[21747:20b] release allPeopleRef
[Session started at 2009-07-31 00:20:05 +0400.]
GNU gdb 6.3.50-20050815 (Apple version gdb-966)
....
Attaching to process 21747.
kill
quit
The Debugger has exited with status 0.(gdb)
按下继续输出 “EXC_BAD_ACCESS” 消息。 Xcode显示,我的代码中最新执行的字符串是CFRelease(addressBookRef);
答
我有同样的问题做类似的事情和进一步的研究,我发现我过了释放。按照Core Foundation docs:
如果创建或复制核心 Foundation对象,必须 随后释放它,当你 完成它。
我读到,作为含义,功能与单词获取不应该被释放你。如果这样做,当真正的所有者试图释放它时,它会在稍后引起问题。所以,当你做这种情况下:
ABRecordRef recordRef = CFArrayGetValueAtIndex(allPeopleRef, i);
及更高版本:
CFRelease(recordRef);
你发布的东西,是不应该被释放。很久以后,当你这样做:
CFRelease(allPeopleRef);
数组将尝试释放其所有记录,不知道你已经释放了一些人。结果是你的错误。通过评论这一行,你可能会让错误消失,但我担心你已经造成了内存泄漏。
我建议你不要在叫CFRelease
获取方法指针,做调用它创建或复制方法指针(可能有例外情况,但到目前为止,它为我的作品)。
答
allPeopleRef和addressBookRef指向相同的对象?副本可能很浅。 ABAddressBookCopyArrayOfAllPeople是做什么的?
ABAddressBookCopyArrayOfAllPeople 返回地址簿中的所有人员记录。 CFArrayRef ABAddressBookCopyArrayOfAllPeople( ABAddressBookRef addressBook ); 参数 地址簿 其人员记录要返回的地址簿。 返回值 包含addressBook中的人员记录的数组。 供货情况 适用于iPhone OS 2.0及更高版本。 声明 ABPerson.h – beefon 2009-07-31 05:19:01
如果您注释掉CFRelease(allPeopleRef),会发生什么情况; ? – Sam 2009-07-31 10:15:15