1

更新:

我相信问题出在我如何存储对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.
4

2 回答 2

1

事实证明,我所需要的只是CFRetain( person )一切都很幸运,再次走运。我还在dealloc我的类中添加了一个以在对象消失时清理指针:

- (void)dealloc {
    CFRelease( _contact );
}

我的代码现在运行顺利静态分析器很高兴(不是说它无论如何都发现了泄漏)。

于 2013-08-07T03:56:07.983 回答
0
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker
      shouldContinueAfterSelectingPerson:(ABRecordRef)person
{
    [self displayPerson:person];
    [self dismissViewControllerAnimated:YES completion:nil];

    return NO;
}

你返回不?

尝试检查该值是否存在

IE

- (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];
    }
}
于 2013-08-07T03:35:35.843 回答