更新
我认为问题在于我如何存储ABRecordRef
的引用。我目前只是挂在peoplePickerNavigationController:shouldContinueAfterSelectingPerson:property:identifier:
而不是CFRetain
或其他任何内容的价值上。从文档中不清楚是否需要保留它。
我正在使用iPhone应用程序,它使用AddressBook和AddressBookUI框架与地址簿连接。我正在使用ABPeoplePickerNavigationController
向用户提供联系人列表以供选择,并将结果ABRecordRef
捕获为自定义类的实例变量。
首次使用时,这一切都正常。但是,第二次时间我从联系人中挑选某人(即使是另一个人),我的应用程序在EXC_BAD_ACCESS
的电话中被ABRecordCopyValue
炸毁。我正在记录指针,每次选择一个联系人时它们肯定是不同的(即使同一个联系人两次)。
我无法理解如何释放此引用。内存泄漏确定,但为什么它第一次工作正常而不是第二次?
这是它正在死的实际召唤:
- (NSString*)displayName {
return CFBridgingRelease( ABRecordCopyValue( self.contact, kABPersonFirstNameProperty ) );
}
如果它有用的话,这里有一些调试输出:
Printing description of self->_contact:
(ABRecordRef) _contact = 0x1f582dc0
(lldb) expr (CFTypeRef)ABRecordCopyValue(self.contact, kABPersonFirstNameProperty)
error: Execution was interrupted, reason: EXC_BAD_ACCESS (code=1, address=0xd1f57cc1).
The process has been returned to the state before execution.
答案 0 :(得分:1)
原来我所需要的只是CFRetain( person )
而且一切都很开心再次幸运。我还在我的类中添加了dealloc
以在对象消失时清理指针:
- (void)dealloc {
CFRelease( _contact );
}
我的代码现在可以顺利运行和静态分析器很高兴(不过它无论如何都会发现泄漏)。
答案 1 :(得分:0)
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker
shouldContinueAfterSelectingPerson:(ABRecordRef)person
{
[self displayPerson:person];
[self dismissViewControllerAnimated:YES completion:nil];
return NO;
}
你回来了吗?
尝试检查该值是否存在
即
- (void)displayPerson:(ABRecordRef)person
{
NSString* companyName = (__bridge_transfer NSString*)ABRecordCopyValue(person, kABPersonOrganizationProperty);
NSString* name = (__bridge_transfer NSString*)ABRecordCopyValue(person, kABPersonFirstNameProperty);
NSString* display = @"";
if (companyName) {
display = companyName;
} else if (name) {
display = name;
} else {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"No Details For Contact"
message:@"Please update contact with company and/or first name"
delegate:nil
cancelButtonTitle:@"Dismiss"
otherButtonTitles:nil];
[alertView show];
}
}