I'm stumped.
I'm trying to get a list of all the email address a person has.
I'm using the ABPeoplePickerNavigationController
to select the person, which all seems fine. I'm setting my
ABRecordRef personDealingWith;
from the person
argument to
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier {
and everything seems fine up till this point. The first time the following code executes, all is well. When subsequently run, I can get issues. First, the code:
// 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);
If compiled as written, the are no errors or static analysis problems. This crashes with a
*** -[Not A Type retain]: message sent to deallocated instance 0x4e9dc60
error.
But wait, there's more! I can fix it in either of two ways.
Firstly, I can uncomment the NSLog at the top of the function. I get a leak from the NSLog's ABRecordCopyValue
every time through, but the code seems to run fine.
Also, I can comment out the
CFRelease(multi);
at the end, which does exactly the same thing. Static compilation errors, but running code.
So without a leak, this function crashes. To prevent a crash, I need to haemorrhage memory. Neither is a great solution.
Can anyone point out what's going on?