2009-07-23 13 views

Respuesta

8

Los dos métodos hacen cosas diferentes. Si posee un temporizador (lo retuvo, lo asignó o lo copió), debe liberarlo. Si lo programó en un ciclo de ejecución, debe invalidarlo para que el ciclo de ejecución lo libere. Si hizo ambas cosas, debe liberar e invalidar el temporizador (sin embargo, normalmente es suficiente tener el ciclo de ejecución que posee el temporizador).

+0

primer lanzamiento y luego invalidar en desasignación? ¿puedo enviar argumentos con dos argumentos en el selector? –

+0

Primero invalídelo y luego suéltelo (si es el propietario). Por favor aclara tu última pregunta. Si está preguntando si puede llamar a invalidar y liberar en el temporizador con una sola llamada, la respuesta es no, a menos que cree su propio método de conveniencia que haga estas dos cosas, y llame a ese método. – Felixyz

+0

¿Puedo enviar argumentos adicionales con @selector en NSTIMER? –

0

Esa es la forma correcta de desasignar un temporizador que aún podría estar ejecutándose (y que desea detener).

+1

asumiendo que usted posee el temporizador en primer lugar ... si no lo hace, la llamada '-reliberará' se bloqueará. O deberia. –

1

Siempre, liberar es lo último que haces. Una vez que libera algo, no hay garantía de que sea seguro desreferenciar el objeto, lo que significa que ya no es seguro enviarlo CUALQUIER mensaje.

15

[timer release] solo necesita ser llamado si "posee" el temporizador. De Apple's documentation:

Debido a que el bucle de ejecución mantiene el temporizador, desde la perspectiva de la gestión de memoria normalmente no hay necesidad de mantener una referencia a un temporizador una vez que se haya programado. Dado que el temporizador se pasa como un argumento cuando especifica su método como un selector, puede invalidar un temporizador de repetición cuando sea apropiado dentro de ese método. Sin embargo, en muchas situaciones, también desea la opción de invalidar el temporizador, tal vez incluso antes de que comience. En este caso, debe mantener una referencia al temporizador para que pueda enviar un mensaje invalidado siempre que sea apropiado. Si crea un temporizador no programado (consulte “Unscheduled Timers”), debe mantener una referencia fuerte al temporizador (en un entorno contado por referencia, lo conserva) para que no sea desasignado antes de usarlo.

¿Qué significa esto?

Si alloc y init un temporizador, también debe release que, de este modo:

NSTimer * timer = [[NSTimer alloc] initWith...]; 

NSRunLoop * runLoop = [NSRunLoop currentRunLoop]; 
[runLoop addTimer:timer forMode:NSDefaultRunLoopMode]; 
[timer release]; 

... 
... 

[timer invalidate]; 
timer = nil; 

Una vez que el temporizador ha sido añadido al bucle de ejecución, no hay ninguna razón para mantener una referencia a él más , ya que los loops de ejecución lo poseen. En este caso, como se muestra, release el temporizador tan pronto como lo agregue al ciclo de ejecución, y luego simplemente invalidate cuando haya terminado. La última línea (ajuste del temporizador a nil) es por seguridad. La llamada a invalidate dará como resultado la liberación del temporizador (por el ciclo de ejecución), por lo que no es seguro mantener una referencia que lo señale. Establecer la referencia local en nil mantiene las cosas kosher.

Sin embargo, si se crea un temporizador usando uno de los métodos de conveniencia, así:

NSTimer * timer = [NSTimer scheduledTimerWithTimeInterval ...]; 

Haces no necesita llamar [timer release] en absoluto! El método de conveniencia agrega el temporizador al bucle de ejecución, que luego lo posee, por lo que no necesita realizar ninguna gestión de memoria en el objeto del temporizador devuelto.Sólo tendría que invalidate el temporizador cuando ya no desea utilizarlo:

[timer invalidate]; 
timer = nil; 

O bien, si el temporizador no se ajusta a repetir, que haría absolutamente nada en absoluto, ya que sería lanzado después de la primera solicitud .

+2

tan pronto como llame a [liberación del temporizador], no es buena forma suponer que el temporizador sigue siendo válido. En el caso de un único método, casi siempre es seguro hacerlo, pero el código sería mejor si se coloca el [lanzamiento del temporizador] después del [invalidación del temporizador]. –

+0

Una gran respuesta práctica. – Ross

Cuestiones relacionadas