gestión de memoria en IOS / ManagedObjectContext
-
11-10-2019 - |
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?
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.