2010-07-30 4 views
0

J'ai un exemple concret que j'ai dans mon projet ci-dessous. Mon but est de choisir le numéro de téléphone le plus probable pour les réceptions SMS, et seulement ce numéro (téléphone). Tout fonctionne bien quand je ne libère pas la mémoire à la fin, mais nous ne pouvons pas avoir cela, pouvons-nous. Ma question est: Où (et comment) est la façon correcte de libérer de la mémoire dans l'exemple ci-dessous?Problèmes de libération de mémoire dans Objective-C

// Called after a person has been selected by the user. Return YES if you want the person to be displayed. 
// Return NO to do nothing (the delegate is responsible for dismissing the peoplepicker) 
- (BOOL) peoplePickerNavigationController: (ABPeoplePickerNavigationController *) peoplePicker 
    shouldContinueAfterSelectingPerson: (ABRecordRef)person 
{  
// Retrieving the person's most likely phonenumber (kABPersonPhoneProperty) 
CFStringRef phoneNumber, phoneNumberLabel; 

ABMutableMultiValueRef multiValueReference = ABMultiValueCreateMutable(kABMultiStringPropertyType); 
multiValueReference = ABRecordCopyValue(person, kABPersonPhoneProperty); 

NSMutableString *mostLikelyPhoneNumber = [[NSMutableString alloc] init]; 

// Iterating through all the phone numbers in the list 
for (CFIndex i = 0; i < ABMultiValueGetCount(multiValueReference); i++) { 

    phoneNumberLabel = ABMultiValueCopyLabelAtIndex(multiValueReference, i); 
    phoneNumber  = ABMultiValueCopyValueAtIndex(multiValueReference, i); 

    // Converting to NSString for easier comparison (this way I have only NSStrings) 
    NSString *NSStringphoneNumberLabel = [[NSString alloc] init]; 
    NSString *NSStringphoneNumber = [[NSString alloc] init]; 

    // Copying the contents of the CFStringRef to my NSString pointers 
    NSStringphoneNumberLabel = (NSString *) phoneNumberLabel; 
    NSStringphoneNumber = (NSString *) phoneNumber; 

    LOG (@"Phone number: %@/%@", phoneNumberLabel, phoneNumber); // No problem so far! 
    LOG (@"Phone number: %@/%@", NSStringphoneNumberLabel, NSStringphoneNumber); // No problem so far! 

    // If this phone number has a "iphone" or a "mobile" label, save it to mostLikelyPhoneNumber 
    if ([NSStringphoneNumberLabel isEqualToString:@"_$!<Mobile>!$_"]) 
    { 
    mostLikelyPhoneNumber = (NSMutableString *) NSStringphoneNumber; 
    } 

    else if ([NSStringphoneNumberLabel isEqualToString:@"iPhone"]) 
    { 
    mostLikelyPhoneNumber = (NSMutableString *) NSStringphoneNumber; 
    // However, if it was an "iphone", break out of the loop. (Can't get any better than iPhone) 
    break; 
    } 

    _tfGSM.text = (NSString*) mostLikelyPhoneNumber; 

    // Releasing memory used in this particular iteration 
    [NSStringphoneNumber release]; 
    [NSStringphoneNumberLabel release]; 
} 

// Releasing rest of memory THIS IS WHERE IT CRASHES! 
[mostLikelyPhoneNumber release]; 
CFRelease(phoneNumberLabel); 
CFRelease(phoneNumber); 
CFRelease(multiValueReference); 

[self dismissModalViewControllerAnimated:YES]; 
return NO; // As soon as a person is picked, we end this address book sidetrip and return to the app 
} 

Répondre

1

Votre problème de base semble ne pas comprendre ce que = signifie.

Lorsque vous attribuez une valeur de pointeur à l'autre, comme dans cet exemple choisi au hasard:

mostLikelyPhoneNumber = (NSMutableString*) NSStringphoneNumber; 

vous n'êtes pas copier le contenu de la deuxième chaîne dans la première chaîne mutable. Au lieu de cela, vous écrasez le pointeur lui-même. Donc le pointeur original vers le NSMutableString que vous avez alloué précédemment est perdu, et vous avez maintenant seulement une deuxième référence à la valeur NSStringphoneNumber, dont vous ne possédez pas.

Vous faites à peu près la même chose partout dans votre code.

Lorsque vous espérez finalement nettoyer, vous ne pouvez pas le faire, car vous n'avez plus de pointeurs sur vos objets alloués; et quand vous essayez, vous libérez plutôt un tas de choses que vous ne possédez pas, conduisant à un crash.

Normalement dans ces situations, je suggère d'aller et de lire le memory management guide, mais franchement, je pense que vous feriez mieux de revenir à l'essentiel et faire un peu de correction C d'abord.

+0

Tant pis, hein. Eh bien, j'apprécie votre réponse. – maralbjo

+0

D'un autre côté, avec quelques ajustements, je l'ai réussi à fonctionner sans crash. Merci de m'avoir indiqué la bonne direction. – maralbjo

Questions connexes