Kit de développement logiciel (SDK) iPhone: EXC_BAD_ACCESS avec CFRelease for ABAddressBookRef

StackOverflow https://stackoverflow.com/questions/1209130

  •  05-07-2019
  •  | 
  •  

Question

il y a une erreur très étrange avec mon code .. En fait, il n'y a pas d'erreur du tout, il suffit que le débogueur commence par " Signal du programme reçu: “EXC_BAD_ACCESS” " message. Quelqu'un peut-il m'aider? Je suis absolument confus ... Merci.

-(NSString *)fullNameForPhone:(NSString *)ph withAlternativeText:(NSString *)text
{
    ABAddressBookRef addressBookRef = ABAddressBookCreate(); 
    NSLog(@"create addressBookRef");
    NSString *stringToReturn = text;

    CFArrayRef allPeopleRef = ABAddressBookCopyArrayOfAllPeople(addressBookRef);  
    NSLog(@"create allPeopleRef");
    CFIndex nPeople = ABAddressBookGetPersonCount(addressBookRef);  

    int i = 0;
    BOOL nameFound = NO;

    while ((i < nPeople) && (!nameFound))
    {
        ABRecordRef recordRef = CFArrayGetValueAtIndex(allPeopleRef, i);
        NSLog(@"   create recordRef");
        CFStringRef allRecordPhonesRef = ABRecordCopyValue(recordRef, kABPersonPhoneProperty);
        NSLog(@"   create allRecordPhonesRef");
        CFIndex nPhones = ABMultiValueGetCount(allRecordPhonesRef);
        int currentPhone = 0;
        for (currentPhone = 0; currentPhone < nPhones; currentPhone++) 
        {
            CFStringRef currentPhoneNumberRef = ABMultiValueCopyValueAtIndex(allRecordPhonesRef, currentPhone);
            NSLog(@"         create currentPhoneNumberRef");
            NSString *currentCleanPhoneNumber = [self cleanPhoneNumberForString:[NSString stringWithFormat:@"%@", currentPhoneNumberRef]];
            if (currentPhoneNumberRef!=NULL)
            {
                NSLog(@"         release currentPhoneNumberRef");
                CFRelease(currentPhoneNumberRef);
            }

            if ([ph isEqualToString:currentCleanPhoneNumber])
            {
                CFStringRef firstName = ABRecordCopyValue(recordRef, kABPersonFirstNameProperty);
                CFStringRef lastName = ABRecordCopyValue(recordRef, kABPersonLastNameProperty);
                NSString *fullName = [self fullNameForFirstName:[NSString stringWithFormat:@"%@", firstName] 
                                                    andLastName:[NSString stringWithFormat:@"%@", lastName]];
                if (firstName != NULL)
                    CFRelease(firstName);
                if (lastName != NULL)
                    CFRelease(lastName);
                stringToReturn = fullName;
                nameFound = YES;
                break;
            }

        }

        CFRelease(allRecordPhonesRef);
        NSLog(@"   release allRecordPhonesRef");
        CFRelease(recordRef);
        NSLog(@"   release recordRef");
        i++;
    }
    CFRelease(allPeopleRef);
    NSLog(@"release allPeopleRef");
    CFRelease(addressBookRef);
    NSLog(@"release addressBookRef");
    return stringToReturn;
}

La sortie de la console est:

2009-07-31 00:20:05.230 abmodular[21747:20b] create addressBookRef
2009-07-31 00:20:05.231 abmodular[21747:20b] create allPeopleRef
2009-07-31 00:20:05.231 abmodular[21747:20b]    create recordRef
2009-07-31 00:20:05.232 abmodular[21747:20b]    create allRecordPhonesRef
2009-07-31 00:20:05.232 abmodular[21747:20b]          create currentPhoneNumberRef
2009-07-31 00:20:05.232 abmodular[21747:20b]          release currentPhoneNumberRef
2009-07-31 00:20:05.232 abmodular[21747:20b]          create currentPhoneNumberRef
2009-07-31 00:20:05.233 abmodular[21747:20b]          release currentPhoneNumberRef
2009-07-31 00:20:05.233 abmodular[21747:20b]    release allRecordPhonesRef
2009-07-31 00:20:05.233 abmodular[21747:20b]    release recordRef
2009-07-31 00:20:05.233 abmodular[21747:20b]    create recordRef
2009-07-31 00:20:05.234 abmodular[21747:20b]    create allRecordPhonesRef
2009-07-31 00:20:05.234 abmodular[21747:20b]          create currentPhoneNumberRef
2009-07-31 00:20:05.234 abmodular[21747:20b]          release currentPhoneNumberRef
2009-07-31 00:20:05.234 abmodular[21747:20b]    release allRecordPhonesRef
2009-07-31 00:20:05.235 abmodular[21747:20b]    release recordRef
2009-07-31 00:20:05.235 abmodular[21747:20b] release allPeopleRef
[Session started at 2009-07-31 00:20:05 +0400.]
GNU gdb 6.3.50-20050815 (Apple version gdb-966)
....
Attaching to process 21747.
kill
quit
The Debugger has exited with status 0.(gdb) 

Appuyez sur Continuer les sorties " EXC_BAD_ACCESS " message. Xcode indique que la dernière chaîne exécutée dans mon code était CFRelease (addressBookRef);

Était-ce utile?

La solution

J'ai eu le même problème en faisant quelque chose de similaire et, après d'autres recherches, j'ai découvert que j'étais trop libéré. Selon le Documents de base de la fondation :

  

Si vous créez ou copiez un core   Objet de fondation, vous devez   relâchez-le ensuite lorsque vous êtes   fini avec elle.

J'ai lu que cela voulait dire que cela fonctionne avec le mot Get ne devrait pas être publié par vous. Si vous le faites, cela posera un problème ultérieurement lorsque le vrai propriétaire tentera de le libérer. Donc, dans ce cas, quand vous faites:

ABRecordRef recordRef = CFArrayGetValueAtIndex(allPeopleRef, i);

et plus tard:

CFRelease(recordRef);

vous publiez quelque chose qui n'est pas censé être publié. Beaucoup plus tard, quand vous le ferez:

CFRelease(allPeopleRef);

le tableau tentera de publier tous ses enregistrements sans savoir que vous en avez déjà publié certains. Le résultat est votre erreur. En commentant cette ligne, vous pouvez avoir fait disparaître l'erreur, mais je crains que vous n'ayez créé une fuite de mémoire.

Je vous suggère de ne pas appeler CFRelease sur les pointeurs de méthode Get et de l'appeler sur Créer ou Copier . pointeurs de méthode (il peut y avoir des exceptions à cette règle mais jusqu'à présent, cela fonctionne pour moi).

Autres conseils

allPeopleRef et addressBookRef désignent-ils les mêmes objets? La copie est probablement peu profonde. Que fait ABAddressBookCopyArrayOfAllPeople?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top