Question

On dirait que je ne comprenais pas la gestion de la mémoire en Objective C ... soupir.

Je le code suivant (notez que dans mon cas, placemark.thoroughfare et placemark.subThoroughfare sont tous deux remplis de données valides, donc les conditions de if seront-TRUE

item est liée à un ManagedObjectContext. Les variables gérées dans item telles que place ont setters / getters créés avec @dynamic. Ainsi, la déclaration est

@property (nonatomic, retain) NSString *place;
@dynamic place;

Plus tard dans le code, dans le ReverseGeocoderDelegate, je y accéder:

- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark *)placemark {

if (placemark.thoroughfare) {
    [item.place release];
    item.place = [NSString stringWithFormat:@"%@ ", placemark.thoroughfare];        
} else {
    [item.place release];
    item.place = @"Unknown Place";
}
if (placemark.thoroughfare && placemark.subThoroughfare) {
// *** problem is here ***
    [item.place release];
    item.place = [NSString stringWithFormat:@"%@ %@", placemark.thoroughfare , placemark.subThoroughfare];
}

Si je ne libère item.place à l'emplacement marqué dans le code, Instruments trouve une fuite de mémoire là. Si je le fais, le programme se bloque dès que j'essaie d'accéder item.place en dehors de la méthode incriminée.

Toutes les idées?

Était-ce utile?

La solution

Tout d'abord, je voudrais changer la logique comme ceci:

NSString *newPlace = nil;

if (placemark.thoroughfare && placemark.subThoroughfare) {
    newPlace = [NSString stringWithFormat:@"%@ %@", placemark.thoroughfare , placemark.subThoroughfare];
}
else {
    if (placemark.thoroughfare) {
        newPlace = [NSString stringWithFormat:@"%@ ", placemark.thoroughfare];
    }
    else {
        newPlace = @"Unknown Place";
    }
}

item.place = newPlace;    // Either nil of valid string can be assigned to

Utilisation de sortie pour re-initialiser le pointeur est tout simplement pas recommandé par beaucoup. Vous ne devez pas le faire si elle était de sauver un peu de mémoire.

Votre logique précédente ne libérant deux fois . Qu'est-ce que la libération n'est d'abord simplement décrémentation retainCount. Si c'est 0, l'objet est désalloué. Objet ne sera pas désallouée jusqu'à ce que son retainCount est 0.

En supposant que votre élément a la propriété conserviez et puisque revient stringWithFormat: chaîne de autoreleased, donc à la 2ème version, vous essayez de libérer ce qui allait être autoreleased de toute façon.

La meilleure façon de dégager un plusieurs fois l'objet est simplement attribuer nil à elle.

Autres conseils

Un point de départ serait de relire sur les propriétés parce que vous n'avez pas besoin de faire `[item.place release] » partout. Ainsi, vous pouvez les supprimer. Le code dynamique créée par le moteur d'exécution pour permettre que la propriété gère automatiquement libérant quoi que ce soit précédemment affecté.

En outre, le [NSString stringWithFormat:... crée un objet autorelease (ne sais pas si vous saviez que :-) ce qui signifie que si vous où la gestion manuelle de la mémoire pour une variable (non une propriété), alors vous devez retenir / libérer. Mais parce que vous utilisez des propriétés, vous n'avez pas.

Je ne vois pas pourquoi les instruments est de trouver une fuite de mémoire. Peut-être un peu de code est plus à faire. Par exemple, si vous êtes allé item.place = [NSString alloc] initWith...]; alors je pense que vous en avez besoin.

Le crash je soupçonne d'être à cause des rejets à l'origine de conserver compte de zéro et de déclenchement des erreurs d'accès mauvais exec.

L'espoir qui aide.

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