2010-04-10 20 views
5

Estoy perplejo.La lectura de la dirección de correo electrónico de los contactos falla con el extraño problema de memoria

Estoy tratando de obtener una lista de todas las direcciones de correo electrónico que tiene una persona. Estoy usando el ABPeoplePickerNavigationController para seleccionar a la persona, lo cual parece estar bien. Soy la creación de mi

ABRecordRef personDealingWith; 

del argumento person a

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier { 

y todo parece estar bien arriba hasta este punto. La primera vez que se ejecuta el siguiente código, todo está bien. Cuando se ejecuta posteriormente, puedo tener problemas. Primero, el código:

// 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); 

Si se compila como está escrito, no hay errores o problemas de análisis estático. Esto bloquea con un error

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

.

Pero espera, ¡hay más! Lo puedo solucionar de dos maneras.

En primer lugar, puedo descomentar el NSLog en la parte superior de la función. Recibo una filtración del NSLog's ABRecordCopyValue todo el tiempo, pero el código parece funcionar bien.

Además, puedo comentar la

CFRelease(multi); 

al final, lo que hace exactamente lo mismo. Errores de compilación estática, pero código en ejecución.

Así que sin una fuga, esta función se bloquea. Para evitar un choque, necesito hemorragia de memoria. Tampoco es una gran solución.

¿Alguien puede señalar qué está pasando?

Respuesta

13

Resultó que no estaba almacenando correctamente la var ABRecordRef personDealingWith. Todavía no estoy seguro de cómo hacerlo correctamente, pero en lugar de tener la funcionalidad en otra rutina (realizada más adelante), ahora estoy haciendo el trabajo pesado en el método de delegado, y utilizando los resultados derivados en mi tiempo libre. La nueva rutina (de trabajo):

- (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; 
} 
0

Me encontré con un problema similar. El problema podría estar en la forma de configurar su

ABRecordRef personDealingWith; 

Parece que no se puede simplemente hacer:

ABRecordRef personDealingWith = person; 

Debido personDealingWith sigue siendo nula. En cambio, lo que hice fue:

ABRecordID personID = ABRecordGetRecordID(person); 
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL); 
personDealingWith = ABAddressBookGetPersonWithRecordID(addressBook, personID); 
Cuestiones relacionadas