¿Cómo puedo solucionar esta advertencia sonido metálico: “Objeto con 0 retienen los recuentos devueltos a la persona que llama, donde 1 (propietaria) retener recuento se espera”?

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

Pregunta

Tengo un pedazo de código Objective-C que tiene el siguiente aspecto:

- (NSString *)copyData:(NSData *)data
{
    NSString *path = [[[self outputDirectory] stringByAppendingPathComponent:@"archive"] stringByAppendingPathExtension:@"zip"];
    NSLog(@"Copying data to %@", path);
    [data writeToFile:path atomically:NO];
    return path;
}

El código se llama desde un inicializador que es similar al siguiente:

- (id)initWithData:(NSData *)data
{
    if ((self = [super init]) != nil) {
        NSString *path = [self copyData:data];        // Line 41 (referenced in warning, shown below)
        return [self initWithContentsOfFile:path];
    }
    return self;
}

Al ejecutar el analizador de sonido metálico estática, consigo las siguientes advertencias para la variable path:

  

potenciales de fuga de un objeto asignado en la línea 41 y se almacenan en 'camino'

     Se espera

Objeto con 0 retener el recuento devueltos a la persona que llama, donde 1 (propietaria) retener recuento

Estoy confundido. Mi entendimiento es que stringByAppendingPathComponent debe devolver una cadena autoreleased, por lo que debe tener una red retener cuenta de 0. (Obviamente no me quiero para retenerlo.)

He intentado alterar copyData: para devolver el siguiente, pero no deshacerse de la advertencia:

return [[path retain] autorelease];

Entonces, ¿cuál es el problema con esta advertencia?

¿Fue útil?

Solución

Sospecho que acaba de darse cuenta de un método con el copy prefijo y marcar que como algo que debe devolver algo que posee la persona que llama, ya que piensa que está siguiendo las convenciones de nomenclatura de cacao.

En su caso, por supuesto, se está refiriendo a los archivos y todo eso, así que es una advertencia puede ignorarse. Si cambia el nombre de su método, a algo así como saveData: lugar, apuesto a la advertencia desaparecerá.

Otros consejos

Además, para los momentos en los que realmente no quiero nombrar un método de 'copia' o algo porque independientemente de las directrices de gestión de memoria de cacao, copia es el mejor nombre para el método, se puede anotar el declairation método con NS_RETURNS_NOT_RETAINED y luego Clang no le dará una advertencia. Por lo tanto:

// Copies data from data to string; does not follow the copy rule
- (NSString*)copyData:(NSData*)data NS_RETURNS_NOT_RETAINED;

Dado que el método tiene la copy nombre en ella, el analizador está a la espera del objeto devuelto a tener un recuento de 1 retienen, según el Guía de gestión de memoria .

No, eso es incorrecto; a menos que el método contiene "alloc", "copia", "nuevo", o una de las otras palabras clave que implica el objeto será propiedad de invocador, el método devuelve un objeto autoreleased o administrado de otra forma, por lo stringByAppendingPathComponent está volviendo una cadena autoreleased .

Además de eso, su método de "copyData", contiene la palabra "copia", lo que implica que el resultado debe ser de propiedad (y puesto en libertad) por el llamador. Sin embargo, el resultado que se ha devuelto autoreleased, por lo tanto, el mensaje de error que te da. Si desea corregir el error, no AutoRelease. Es decir:

 return [path retain]

Por supuesto que implica que las personas que llaman de su necesidad función para liberarlo. Alternativamente, se puede cambiar el nombre de la función para que cumpla con las directrices de gestión de memoria.

El nombre "copyData", en mi humilde opinión, es poco intuitivo de todos modos. Yo sugeriría cambiar el nombre de su función en "pathToSavedDataWithData" o similares. Algo que dice lo que realmente está haciendo.

Me voy a tomar una puñalada en esto y supongo que no puedes encontrar el mismo mensaje de error exacto, si es o no el nombre de su rutina comenzó con "copia ..." o no. Me acaba de terminar en una situación similar y "copia" no era parte del nombre de la rutina que estaba llamando. Tañido estaba dando el mensaje de error, simplemente porque me estaba volviendo un objeto autoreleased, una situación peligrosa. Haciendo el

  return [path retain]  

truco al final como se recomienda por Michael se hizo cargo del problema.

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