2009-09-15 10 views

Respuesta

42

En primer lugar, desea mantener un puntero al temporizador

self.packetTimer = [NSTimer timerWithTimeInterval:CONNECTION_TIMEOUT target:self selector:@selector(connectionTimeout:) userInfo:nil repeats:NO]; 
[[NSRunLoop currentRunLoop] addTimer:packetTimer forMode:NSDefaultRunLoopMode]; 

Si algún otro sitio en el código que desea cancelar, simplemente llame a:

[self.packetTimer invalidate]; 
self.packetTimer = nil; 
+1

¿No deberías suelte el temporizador antes de configurarlo a cero? 'invalidate' hará que el ciclo de ejecución libere su referencia, pero hay un retener adicional aquí cuando se asigna a' packetTimer'. –

+1

Eso es verdad. Corregido – coneybeare

+0

Hmm. Esto no me parece correcto. Sebatsien está en lo cierto: cuando asigna el temporizador a self.packetTimer (suponiendo que sea una propiedad retener), entonces hay un retener. Agregarlo al runloop es un segundo retener. Cuando lo invalides más tarde, hay un lanzamiento interno. Creo que necesitas una [versión de auto.packetTimer} explícita justo después de la invalidación y justo antes de configurar self.packetTimer a nil. ¿Me equivoco? – Marc

101
@interface 
    NSTimer *autoTimer; 

@implementation 

// Start timer 
    autoTimer = [NSTimer scheduledTimerWithTimeInterval:(3.0) 
     target:self 
     selector:@selector(autoTimerFired:) 
     userInfo:nil 
     repeats:YES]; 

// Stop timer: 
    [autoTimer invalidate]; 
    autoTimer = nil; 
+20

En Swift, por supuesto, 'autoTimer.invalidate()', y no hay necesidad de establecer 'null'. – Joe

+0

En Swift, si lo configura en cero, el temporizador aún puede disparar. Esto me pasó a mí. – kkazakov

+0

¡POR LO TANTO DEBE 'INVALIDARLO' @kkazakov! –