Pregunta

Estoy creando una aplicación para iPhone donde separo algunos hilos para hacer un trabajo de larga duración en segundo plano para no colgar la interfaz de usuario. Entiendo que los subprocesos necesitan instancias NSAutoreleasePool para la administración de la memoria. De lo que no estoy seguro es si el método de subproceso llama a otro método: ¿ese método también necesita un NSAutoreleasePool?

Código de ejemplo:

- (void)primaryMethod {
    [self performSelectorInBackground:@selector(threadedMethod) withObject:nil];
}

- (void)threadedMethod {
    NSAutoreleasePool *aPool = [[NSAutoreleasePool alloc] init];

    // Some code here

    [self anotherMethod];

    // Maybe more code here

    [aPool drain];
}

- (void)anotherMethod {
    // More code here
}

La razón por la que pregunto es que recibo errores de que los objetos se vuelven a liberar automáticamente sin un grupo en su lugar, y simplemente están "goteando".

He visto otras preguntas en las que las personas no tenían grupos de liberación automática, y entiendo por qué se necesita un grupo de liberación automática. Estoy específicamente interesado en averiguar si un grupo de liberación automática creado en (en este ejemplo) threaddedMethod se aplica a los objetos creados en anotherMethod .

¿Fue útil?

Solución

Para responder a su pregunta, sí, otro Método está utilizando el NSAutoreleasePool que creó en threaddedMethod, y todo lo que libere automáticamente allí se liberará cuando se libere / drene un Grupo.

Por lo tanto, es poco probable que su error provenga directamente de este código (a menos que haya más)

Ponga un punto de interrupción en _NSAutoreleaseNoPool (agréguelo por nombre en la ventana de puntos de interrupción) y ejecute su código en el depurador y se detendrá cuando se llame la liberación automática sin un grupo y eso debería resolver su problema.

Otros consejos

En su ejemplo, sí, NSAutoreleasePool está llevando a través de métodos ya que la invocación de [self anotherMethod] está anidada dentro - (void) threaddedMethod .

  • P: ¿NSAutoreleasePool transporta los métodos?
  • A: Depende:
    1. A través de invocaciones anidadas, sí.
    2. Entre invocaciones de hermanos, no.

Y pase lo que pase, la instancia de NSAutoreleasePool queda fuera de alcance cuando el alcance primario desaparece. -en su ejemplo, al final de - (void) threaddedMethod {} .

El artículo mencionado anteriormente ( http://thegothicparty.com/dev/macos/nsautoreleasepool/ ) es bastante claro al respecto.

El grupo de liberación automática se transfiere a otro método. Sin embargo, cuando finaliza su función de subprocesos, debe llamar a [aPool release] en lugar de [aPool drain]. Son más o menos equivalentes, pero la liberación de un grupo hace que el grupo NSAutoreleasePool se libere a sí mismo además de todos los demás objetos del grupo. Cuando su función de subproceso finaliza después de llamar a drenaje, el grupo de liberación automática todavía tiene un conteo de retención de +1 Las probabilidades son, el " simplemente goteando " ¡El objeto es una piscina!

EDITAR:

Jim Puls tiene razón acerca de que la liberación y el drenaje son equivalentes. Los documentos de Apple dicen claramente que son idénticos en el entorno sin recolección de basura, y que el drenaje es mejor en el caso de recolección de basura. ¡Mi culpa por no leer los documentos!

Aquí hay un artículo que presenta una descripción general de NSAutoreleasePools: debería ayudarlo a orientarse en la dirección correcta. Dado que hay una pila virtual de grupos de liberación automática, el más alto se usará en todas partes dentro de su aplicación, independientemente de dónde se liberen automáticamente los objetos.

http://thegothicparty.com/dev/macos/nsautoreleasepool/

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