从联系人中读取电子邮件地址失败,出现奇怪的内存问题。

5

我被卡住了。

我正在尝试获取一个人拥有的所有电子邮件地址列表。 我正在使用ABPeoplePickerNavigationController来选择该人员,这一切似乎都很好。我正在设置我的

ABRecordRef personDealingWith;

person参数到

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier {

一切似乎都很好,直到这个点。 第一次执行以下代码时,一切正常。 但在后续运行时,可能会出现问题。首先是这段代码:

// following line seems to make the difference (issue 1)
// NSLog(@"%d", ABMultiValueGetCount(ABRecordCopyValue(personDealingWith, kABPersonEmailProperty)));

// construct array of emails
ABMultiValueRef multi = ABRecordCopyValue(personDealingWith, kABPersonEmailProperty);
CFIndex emailCount = ABMultiValueGetCount(multi);

if (emailCount > 0) {
    // collect all emails in array
    for (CFIndex i = 0; i < emailCount; i++) {
        CFStringRef emailRef = ABMultiValueCopyValueAtIndex(multi, i);
        [emailArray addObject:(NSString *)emailRef];
        CFRelease(emailRef);
    }
}

// following line also matters (issue 2)
CFRelease(multi);

如果按照原样编译,就不会有错误或静态分析问题。这会导致一个错误:*** -[Not A Type retain]: message sent to deallocated instance 0x4e9dc60
但是等等,还有更多的解决方法!我可以通过两种方式之一来解决它。
首先,我可以取消函数顶部的NSLog注释。每次经过时,我都会从NSLog的ABRecordCopyValue中得到一个泄漏,但代码似乎运行良好。
此外,我可以将其注释掉。
CFRelease(multi);

最终,它做了完全相同的事情。静态编译错误,但运行代码。

因此,如果没有泄漏,这个函数就会崩溃。为了防止崩溃,我需要流失内存。两者都不是很好的解决方案。

有人能指出发生了什么吗?

2个回答

13

结果发现我没有正确地存储ABRecordRef personDealingWith变量。我仍然不确定如何正确地做到这一点,但是现在我已经将功能放在委托方法中,而不是在另一个例程中(稍后执行),我正在使用派生的结果。新的(有效)例程:

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person {
    // as soon as they select someone, return
    personDealingWithFullName = (NSString *)ABRecordCopyCompositeName(person);
    personDealingWithFirstName = (NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty);
    // construct array of emails
    [personDealingWithEmails removeAllObjects];
    ABMutableMultiValueRef multi = ABRecordCopyValue(person, kABPersonEmailProperty);
    if (ABMultiValueGetCount(multi) > 0) {
        // collect all emails in array
        for (CFIndex i = 0; i < ABMultiValueGetCount(multi); i++) {
            CFStringRef emailRef = ABMultiValueCopyValueAtIndex(multi, i);
            [personDealingWithEmails addObject:(NSString *)emailRef];
            CFRelease(emailRef);
        }
    }
    CFRelease(multi);
    return NO;
}

0

我遇到了类似的问题。问题可能在于您设置的方式。

ABRecordRef personDealingWith;

看起来你不能只是这样做:

ABRecordRef personDealingWith = person;

因为personDealingWith仍然为空。所以我做的是:

ABRecordID personID = ABRecordGetRecordID(person);
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL);
personDealingWith = ABAddressBookGetPersonWithRecordID(addressBook, personID);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接