title: Memory leaks with AddressBook framework
body: <p>I'm having some memory leaks with both ABAddressBookGetPersonWithRecordID and ABPersonSetImageData. I've been looking for solutions before posting here but I still don't understand. If I play quite a long time with the iPhone 3GS or with only a few contacts with iPhone 3G, actually the application crashes.  Here is my code in the didSelectRowAtIndexPath method. I've seen sample codes with these methods and I don't see what I'm missing. Thank you in advance. (sorry for mistakes...)</p>
  
  <p><code></p>
  
  <pre><code>Contact *myContact = [fetchedResultsController objectAtIndexPath:indexPath];
  
  cancelCreateContact = NO;
  
  
  ABAddressBookRef ab = ABAddressBookCreate();
  int len = ABAddressBookGetPersonCount(ab);
  ABRecordID contactID;
  ABRecordRef person;
  BOOL alreadyExists = NO;
  CFStringRef first, last;
  
  for(int i = 1; i &lt; (len + 1); i++)
  {
      person = ABAddressBookGetPersonWithRecordID(ab, (ABRecordID)i);
  
      if(!person){
          len++;
          continue;
      }
  
      first = ABRecordCopyValue(person, kABPersonFirstNameProperty);
      last = ABRecordCopyValue(person, kABPersonLastNameProperty);
  
      if ([[(NSString*)first lowercaseString] isEqualToString:[myContact.firstname lowercaseString]] &amp;&amp; [[(NSString*)last lowercaseString] isEqualToString:[myContact.lastname lowercaseString]]) {
          alreadyExists = YES;
          contactID = ABRecordGetRecordID(person);
          break;
      }
  }
  
  if (alreadyExists) {
      //NSLog(@"already exists");
      ABRecordRef aContactFound = ABAddressBookGetPersonWithRecordID(ab, contactID);
  
      ABRecordRef aRecord = ABPersonCreate();
  
      CFErrorRef anError = NULL;
  
      CFStringRef firstname = ABRecordCopyValue(aContactFound, kABPersonFirstNameProperty);
      ABRecordSetValue(aRecord, kABPersonFirstNameProperty, firstname, &amp;anError);
      CFRelease(firstname);
  
      CFStringRef lastname = ABRecordCopyValue(aContactFound, kABPersonLastNameProperty);
      ABRecordSetValue(aRecord, kABPersonLastNameProperty, lastname, &amp;anError);
      CFRelease(lastname);
  
      CFStringRef job = ABRecordCopyValue(aContactFound, kABPersonJobTitleProperty);
      ABRecordSetValue(aRecord, kABPersonJobTitleProperty, job, &amp;anError);
      CFRelease(job);
  
      ABMultiValueRef instantMessage = ABRecordCopyValue(aContactFound, kABPersonInstantMessageProperty);
      ABRecordSetValue(aRecord, kABPersonInstantMessageProperty, instantMessage, &amp;anError);
      CFRelease(instantMessage);
  
      ABMultiValueRef phone = ABRecordCopyValue(aContactFound, kABPersonPhoneProperty);
      ABRecordSetValue(aRecord, kABPersonPhoneProperty, phone, &amp;anError);
      CFRelease(phone);
  
      ABMultiValueRef email = ABRecordCopyValue(aContactFound, kABPersonEmailProperty);
      ABRecordSetValue(aRecord, kABPersonEmailProperty, email, &amp;anError);
      CFRelease(email);
  
      CFDataRef imageData = ABPersonCopyImageData(aContactFound);
      ABPersonSetImageData(aRecord, imageData, &amp;anError);
      ABAddressBookSave(ab, &amp;anError);
      CFRelease(imageData);
  
      ABUnknownPersonViewController *ABView = [[ABUnknownPersonViewController alloc] init];
      ABView.unknownPersonViewDelegate = self;
      ABView.displayedPerson = aRecord;
      ABView.allowsAddingToAddressBook = NO;
      ABView.allowsActions = YES;
      ABView.hidesBottomBarWhenPushed = YES;
  
      [self.navigationController pushViewController:ABView animated:YES];
  
      [ABView release];
  
      CFRelease(aRecord);
  
  }else{
      //NSLog(@"doesn't exist");
      //sinon ouvre une fiche pré-remplie
  
      ABRecordRef aRecord = ABPersonCreate();
  
      CFErrorRef anError = nil;
  
      if(![myContact.firstname isEqualToString:@""]) ABRecordSetValue(aRecord, kABPersonFirstNameProperty, myContact.firstname, &amp;anError);
  
      if(![myContact.lastname isEqualToString:@""]) ABRecordSetValue(aRecord, kABPersonLastNameProperty, myContact.lastname, &amp;anError);
  
      if(![myContact.email isEqualToString:@""]) {
          ABMultiValueRef ABemail = ABMultiValueCreateMutable(kABMultiStringPropertyType);
          ABMultiValueAddValueAndLabel(ABemail, myContact.email, kABWorkLabel, NULL);
          ABRecordSetValue(aRecord, kABPersonEmailProperty, ABemail, &amp;anError);
          CFRelease(ABemail);
      }
  
      if(![myContact.phone_business isEqualToString:@""] || ![myContact.phone_mobile isEqualToString:@""]){ 
          ABMultiValueRef ABphones = ABMultiValueCreateMutable(kABMultiStringPropertyType);
          if(![myContact.phone_business isEqualToString:@""]) ([myContact.phone_business stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]].length == 4 || [myContact.phone_business stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]].length == 5) ? ABMultiValueAddValueAndLabel(ABphones, [NSString stringWithFormat:@"014443%@", myContact.phone_business], kABPersonPhoneMainLabel, NULL) : ABMultiValueAddValueAndLabel(ABphones, myContact.phone_business, kABPersonPhoneMainLabel, NULL);
          if(![myContact.phone_mobile isEqualToString:@""] &amp;&amp; ([myContact.phone_mobile stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]].length == 10)) ABMultiValueAddValueAndLabel(ABphones, myContact.phone_mobile, kABPersonPhoneMobileLabel, NULL);
          ABRecordSetValue(aRecord, kABPersonPhoneProperty, ABphones, &amp;anError);
          CFRelease(ABphones);
      }
  
      if(![myContact.job isEqualToString:@""]) ABRecordSetValue(aRecord, kABPersonJobTitleProperty, myContact.job, &amp;anError);
  
      if(![myContact.msn isEqualToString:@""] || ![myContact.twitter isEqualToString:@""] || ![myContact.facebook isEqualToString:@""]){  
          ABMultiValueRef ABmessaging = ABMultiValueCreateMutable(kABMultiDictionaryPropertyType);
          NSMutableDictionary *dMessaging;
  
          if(![myContact.msn isEqualToString:@""]){
              dMessaging = [[NSMutableDictionary alloc] init];
              [dMessaging setObject:myContact.msn forKey:(NSString *) kABPersonInstantMessageUsernameKey];
              [dMessaging setObject:@"MSN" forKey:(NSString *)kABPersonInstantMessageServiceKey];
              ABMultiValueAddValueAndLabel(ABmessaging, dMessaging, kABPersonInstantMessageServiceMSN, NULL);
              [dMessaging release];
          }
  
          if(![myContact.twitter isEqualToString:@""]){
              dMessaging = [[NSMutableDictionary alloc] init];
              [dMessaging setObject:myContact.twitter forKey:(NSString *) kABPersonInstantMessageUsernameKey];
              [dMessaging setObject:@"Twitter" forKey:(NSString *)kABPersonInstantMessageServiceKey];
              ABMultiValueAddValueAndLabel(ABmessaging, dMessaging, kABOtherLabel, NULL);
              [dMessaging release];
          }
  
          if(![myContact.facebook isEqualToString:@""]){
              dMessaging = [[NSMutableDictionary alloc] init];
              [dMessaging setObject:myContact.facebook forKey:(NSString *) kABPersonInstantMessageUsernameKey];
              [dMessaging setObject:@"Facebook" forKey:(NSString *)kABPersonInstantMessageServiceKey];
              ABMultiValueAddValueAndLabel(ABmessaging, dMessaging, kABOtherLabel, NULL);
              [dMessaging release];
  
          }
  
  
          ABRecordSetValue(aRecord, kABPersonInstantMessageProperty, ABmessaging, &amp;anError);
          CFRelease(ABmessaging);
      }
  
      //pas dans l'XMLToObjectParser parce que ça prenait une plombe...
      NSURL *url = [NSURL URLWithString:myContact.picture_path];
      NSData *data = [NSData dataWithContentsOfURL:url];
  
      if(!data){
          NSString *picture_path = (![myContact.gender isEqualToString:@""]) ? [NSString stringWithFormat:@"default_%@_head.png", [myContact.gender lowercaseString]] : @"default_m_head.png";
  
          [myContact setPicture_path:picture_path];
          NSError *error = nil;
          if(![self.managedObjectContext save:&amp;error]){
              NSLog(@"pb lors de l'enregistrement de picture path");
          }
  
          //NSData *localData = [NSData dataWithContentsOfFile:myContact.picture_path];
          UIImage *image = [UIImage imageNamed:picture_path];
          NSData *localData = UIImagePNGRepresentation(image);   
  
          CFDataRef cfLocalData = CFDataCreate(NULL, [localData bytes], [localData length]);
          ABPersonSetImageData(aRecord, cfLocalData, &amp;anError);
          ABAddressBookSave(ab, &amp;anError);
          CFRelease(cfLocalData);
  
      }else {
          UIImage *image = [UIImage imageWithData:data];
          NSString *extension = [(NSArray*)[myContact.picture_path componentsSeparatedByString:@"."] objectAtIndex:1];
  
          NSData *localData = ([extension isEqualToString:@"png"]) ? UIImagePNGRepresentation(image) : UIImageJPEGRepresentation(image, 1.0f);   
  
          CFDataRef cfLocalData = CFDataCreate(NULL, [localData bytes], [localData length]);
          ABPersonSetImageData(aRecord, cfLocalData, &amp;anError);
          ABAddressBookSave(ab, &amp;anError);
          CFRelease(cfLocalData);
      }
  
      if (anError != nil) { NSLog(@"error :: %@", anError); } 
  
  
  
      ABUnknownPersonViewController *ABView = [[ABUnknownPersonViewController alloc] init];
      ABView.unknownPersonViewDelegate = self;
      ABView.displayedPerson = aRecord;
      ABView.allowsAddingToAddressBook = YES;
      ABView.allowsActions = YES;
      ABView.hidesBottomBarWhenPushed = YES;
  
      [self.navigationController pushViewController:ABView animated:YES];
  
  
      [ABView release];
  
      CFRelease(aRecord);
  
  }
  CFRelease(ab);
  </code></pre>
  
  <p></code></p>