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

Def*_*Day 5 iphone memory-leaks contacts addressbook

我很难过.

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

ABRecordRef personDealingWith;
Run Code Online (Sandbox Code Playgroud)

person论证到

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier {
Run Code Online (Sandbox Code Playgroud)

到目前为止,一切似乎都很好.下面的代码第一次执行,一切都很好.随后运行时,我可以解决问题.一,代码:

// 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);
Run Code Online (Sandbox Code Playgroud)

如果编写为编写,则没有错误或静态分析问题.这与一个崩溃

*** -[Not A Type retain]: message sent to deallocated instance 0x4e9dc60

错误.

但等等,还有更多!我可以通过两种方式解决它.

首先,我可以在函数顶部取消注释NSLog.我ABRecordCopyValue每次都从NSLog中泄漏,但代码似乎运行正常.

另外,我可以评论出来

CFRelease(multi);
Run Code Online (Sandbox Code Playgroud)

最后,这完全是一回事.静态编译错误,但正在运行代码.

所以没有泄漏,这个功能崩溃了.为了防止崩溃,我需要出血记忆.两者都不是一个好的解决方案.

谁能指出发生了什么?

Def*_*Day 13

原来我没有ABRecordRef personDealingWith正确存储var.我仍然不确定如何正确地做到这一点,但是我没有在另一个例程中执行该功能(稍后执行),而是在委托方法中执行grunt-work,并在我的闲暇时使用派生结果.新的(工作)例程:

- (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;
}
Run Code Online (Sandbox Code Playgroud)