Pregunta

Parece que no comprendía la gestión de memoria en C Objetivo ... suspiro.

Tengo el siguiente código (nota que en mi caso, placemark.thoroughfare y placemark.subThoroughfare son a la vez llenos de datos válidos, por lo tanto if condiciones serán TRUE

item está ligado a una ManagedObjectContext. Las variables gestionadas en item como place tienen setters / captadores creados con @dynamic. Por lo tanto, la declaración es

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

Más adelante en el código, en el ReverseGeocoderDelegate, puedo acceder a él:

- (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 no me libero item.place en el lugar marcado en el código, Instrumentos encuentra una pérdida de memoria allí. Si lo hago, el programa se bloquea tan pronto como intento acceder item.place fuera del método ofender.

¿Alguna idea?

¿Fue útil?

Solución

En primer lugar, me gustaría cambiar la lógica de esta manera:

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

El uso de estreno de puntero simplemente re-inicialización no es tan recomendado por muchos. Usted no tiene que hacer esto si se trataba de salvar algo de memoria.

Su lógica anterior no liberar dos veces . Lo que hace la liberación inicial es simplemente disminuyendo retainCount. Si es 0, entonces el objeto se cancela la asignación. Objeto no se cancela la asignación hasta su retainCount es 0.

Asumiendo que su la tiene la propiedad retiene y desde cadena devuelve stringWithFormat: autoreleased, por lo que en la segunda versión, que estaba tratando de liberar lo que iba a ser autoreleased de todos modos.

La mejor manera de limpiar un objeto varias veces es simplemente asignando nil a él.

Otros consejos

Un punto de partida sería la de volver a leer acerca de las propiedades, ya que no necesita hacer `[item.place Release]' en cualquier lugar. Para que pueda eliminarlos. El código dinámico creado por el tiempo de ejecución para permitir que la propiedad de forma automática la liberación de asas nada previamente asignado.

Además, el [NSString stringWithFormat:... crea un objeto disparador automático (no estoy seguro si supieras que :-) Lo que significa que si en la administración manual de la memoria para una variable (no una propiedad), entonces tendría que retener / liberarlo. Pero debido a que está utilizando propiedades, no lo hace.

No se puede ver por qué instrumentos es encontrar una pérdida de memoria. Tal vez algún código más arriba es que ver con ello. Por ejemplo, si usted fue item.place = [NSString alloc] initWith...]; entonces creo que lo necesitaría.

El accidente sospecharía que es debido a las liberaciones causando retener los recuentos sean cero y que desencadenan errores de acceso malas Exec.

Espero que ayude.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top