Nested bridge transfer call with ARC

201 views Asked by At

I'm trying to get the email address of a contact and the type of the email address (work/home). This is the code I've written

//Assume that 'personRef' of type ABRecordRef is available
....
ABMultiValueRef emailRef = ABRecordCopyValue(personRef, kABPersonEmailProperty);
NSMutableArray *emailAddresses = nil, *emailAddressLabels = nil;
int ctr = ABMultiValueGetCount(emailRef);
if(ctr!=0) {
    emailAddresses = [[NSMutableArray alloc]init];
    emailAddressLabels = [[NSMutableArray alloc]init];
    for(int i=0; i<ctr; i++) {
        NSString *eId = (__bridge_transfer NSString*)ABMultiValueCopyValueAtIndex(emailRef, i);
        [emailAddresses addObject:eId];
        CFStringRef label = ABMultiValueCopyLabelAtIndex (emailRef, i);
        if(label!=NULL) {
            NSString *eType = (__bridge_transfer NSString*)ABAddressBookCopyLocalizedLabel(label);
            if([eType isEqualToString:@""]) {
                [emailAddressLabels addObject:@"Email"];
            } else {
                [emailAddressLabels addObject:eType];
            }
            CFRelease(label);
        }
    }
}

The code crashes at CFRelease(label), but to prevent memory leak, I should be doing it. When I try the following

NSString *eType = (__bridge_transfer NSString*) ABAddressBookCopyLocalizedLabel(ABMultiValueCopyLabelAtIndex (emailRef, i));

I get the following warning from ARC

1. Call to function 'ABMultiValueCopyLabelAtIndex' returns a Core Foundation object with a +1 retain count
2. Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1

Now the question I have is, How to do a nesting __bridge_transfer call?

1

There are 1 answers

0
JTAS On
NSString *eType = (__bridge_transfer NSString*)
    ABAddressBookCopyLocalizedLabel(
        ABMultiValueCopyLabelAtIndex (emailRef, i) /* <-- this object is leaked */
    );

This code is invalid because you leak the Label here (which I realise is your point I guess?).

You should run that code under the Instruments NSZombie instrument, it will trace all the retain/releases and you'll have a clue what's going on, because frankly, looking at the code, I don't see why it's wrong.