1

I am building an app that requres me to load all the contacts in the datasource of the table from the iPhone AddressBook. On running

Build and Analyze

for the following snippet

ABAddressBookRef addressBook = ABAddressBookCreate(); 
int nPeople = ABAddressBookGetPersonCount(addressBook); 
CFRelease(addressBook);

for(int i=0; i < nPeople; i++ ){
    //ABRecordRef person = [allPeople objectAtIndex:i];
    NSString *name = @"";
    if(ABRecordCopyValue([allPeople objectAtIndex:i], kABPersonFirstNameProperty) != NULL)
        name = [[NSString stringWithFormat:@"%@", ABRecordCopyValue([allPeople objectAtIndex:i], kABPersonFirstNameProperty)] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
    [dataSource addObject: name];
}

[allPeople release];

I am getting a potential memory leak for the line

name = [[NSString stringWithFormat:@"%@", ABRecordCopyValue([allPeople objectAtIndex:i], kABPersonFirstNameProperty)] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];

I am really tired of fixing it but was unable to. Kindly help me out.

Any kind of help would be highly appriciated.

Thanks in advance!!

devsri
  • 6,173
  • 5
  • 32
  • 40

3 Answers3

4

You aren't releasing the result of ABRecordCopyValue; try assigning it to a variable and release it and the end of the loop. Using a variable will also make your code a lot easier to read and highlight the cause of these issues better.

BTW, you are also calling ABRecordCopyValue twice with the same arguments, you should only do it once (using a variable as mentioned above).

newenglander
  • 2,019
  • 24
  • 55
vickirk
  • 3,979
  • 2
  • 22
  • 37
  • Hey could you please help me out in this as well http://stackoverflow.com/questions/4991247/getting-warning-in-setting-delegate-for-abpeoplepickernavigationcontroller thanks – devsri Feb 14 '11 at 11:41
2

I think you can do like below:

CFTypeRef copiedValue = ABRecordCopyValue([allPeople objectAtIndex:i], kABPersonFirstNameProperty);
name = [[NSString stringWithFormat:@"%@", copiedValue] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
CFRelease(copiedValue);
1

You can directly bridge to an NSString. It may be a little more clear:

CFTypeRef fn_typeref = ABRecordCopyValue(person, kABPersonFirstNameProperty);
CFTypeRef ln_typeref = ABRecordCopyValue(person, kABPersonLastNameProperty);

NSString * firstName = (__bridge NSString *) fn_typeref;
NSString * lastName  = (__bridge NSString *) ln_typeref;

NSLog(@"Name:%@ %@", firstName, lastName);

CFRelease(fn_typeref);    // releasing CFTypeRef
CFRelease(ln_typeref);

// use firstName and lastName down here
NSLog(@"Name:%@ %@", firstName, lastName);
atreat
  • 4,243
  • 1
  • 30
  • 34
  • Can it be problems with memory here? Because I'm not sure that bridge makes copies of strings. But next, you release CF references and you use NSStrings after that. – Vladimir Vlasov Jan 24 '17 at 12:36