2010-11-13 5 views
2

J'ai le code suivant:EXC_BAD_ACCESS lors de l'ajout de contacts à partir du répertoire?

ABAddressBookRef ab; 
ab = ABAddressBookCreate(); 
int len = (int) ABAddressBookGetPersonCount(ab); 
int i; 
for(i = 1; i < (len + 1); i++) 
{ 
    ABRecordRef person = ABAddressBookGetPersonWithRecordID(ab,(ABRecordID) i); 
    CFStringRef firstName, lastName; 
    firstName = ABRecordCopyValue(person, kABPersonFirstNameProperty); 
    lastName = ABRecordCopyValue(person, kABPersonLastNameProperty); 
    static char* fallback = ""; 
    int fbLength = strlen(fallback); 
    int firstNameLength = fbLength; 
    bool firstNameFallback = true; 
    int lastNameLength = fbLength; 
    bool lastNameFallback = true; 
    if (firstName != NULL) 
    { 
    firstNameLength = (int) CFStringGetLength(firstName); 
    firstNameFallback = false; 
    } 
    if (lastName != NULL) 
    { 
    lastNameLength = (int) CFStringGetLength(lastName); 
    lastNameFallback = false; 
    } 
    if (firstNameLength == 0) 
    { 
    firstNameLength = fbLength; 
    firstNameFallback = true; 
    } 
    if (lastNameLength == 0) 
    { 
    lastNameLength = fbLength; 
    lastNameFallback = true; 
    } 
    firstNameString = malloc(sizeof(char)*(firstNameLength+1)); 
    lastNameString = malloc(sizeof(char)*(lastNameLength+1)); 
    if (firstNameFallback == true) 
    { 
    strcpy(firstNameString, fallback); 
    } 
    else 
    { 
    CFStringGetCString(firstName, firstNameString, 10*CFStringGetLength(firstName), kCFStringEncodingASCII); 
    } 
    if (lastNameFallback == true) 
    { 
    strcpy(lastNameString, fallback); 
    } 
    else 
    { 
    CFStringGetCString(lastName, lastNameString, 10*CFStringGetLength(lastName), kCFStringEncodingASCII); 
    } 


    printf("%d.\t%s %s\n", i, firstNameString, lastNameString); 
    NSString *fname= [NSString stringWithFormat:@"%s",firstNameString]; 
    NSString *lname= [NSString stringWithFormat:@"%s",lastNameString]; 
    [dict setValue:fname forKey:@"fname"]; 
    [dict setValue:lname forKey:@"lname"]; 
    [self.arrname addObject:[dict copy]]; 

if (firstName != NULL) 
{ 
    CFRelease(firstName); 
} 
if (lastName != NULL) 
{ 
    CFRelease(lastName); 
} 

free(firstNameString); 
free(lastNameString); 

} 

il fonctionne bien pour la première fois.

Mais lorsque je supprime un enregistrement de la liste de contacts, puis j'essaie d'ajouter mon enregistrement à ma requête à l'énoncé suivant.

firstName = ABRecordCopyValue(person, kABPersonFirstNameProperty); 

Quelqu'un peut-il résoudre ce problème? Toute idée est grandement appréciée.

Répondre

4

Il n'y a aucune garantie que le ABRecordID valide commence à 1 et se termine à ABAddressBookGetPersonCount(addressBook). Vous ne pouvez pas utiliser la boucle for en utilisant ABRecordID.

Au lieu de cela, obtenir le CFArray contenant toutes les personnes utilisant ABAddressBookCopyArrayOfAllPeople et itérer dessus.

Un autre commentaire est que vous ne devriez pas utiliser la chaîne C; la plupart des choses peuvent être faites en utilisant l'API de CFString et NSString, qui prend en charge Unicode prêt à l'emploi. En obtenant la chaîne C spécifiant kCFStringEncodingASCII, vous détruisez des lettres comme é ou ü, ગુજરાતી ou 案. (Notez que CFStringGetCString avec kCFStringEncodingASCII est assez difficile et supprime les caractères qui ne sont pas dans l'ASCII, il ne vous donne pas de représentation UTF8 de la chaîne.) Il y a beaucoup de gens dont le nom contient des caractères non-ASCII. Donc, s'il vous plaît, apprenez les méthodes CFString et NSString. Notez qu'un CFStringRef et un NSString* peuvent être échangés librement.

+0

Merci beaucoup .. ça marche bien maintenant. Génial... –

Questions connexes