2012-03-29 25 views
27

En ios5.0 con ARC, en mi controlador de root, invoco un método en un objeto de administrador de seguridad que está en manos del delegado de la aplicación. En ese método configuré el temporizador como sigueNSTimer no activa el selector

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self 
             selector:@selector(updateModel:) userInfo:str repeats:YES]; 
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; 

Sin embargo, esto nunca dispara el selector, es decir. updateModel: nunca se llama. ¿Qué puede estar mal? ¿Hay alguna otra forma más eficiente de hacerlo sin usar NStimer?

Respuesta

10

Pareces estar un poco confundido con tu variable de temporizador.

Inicializa un nuevo temporizador pero no lo está usando realmente. ¿Desea utilizar el temporizador que inicializó o desea utilizar ApplicationDelegate.timer?

Aquí están las dos posibles soluciones.

Opción uno (asumiendo que tiene una instancia de clase titulada ApplicationDelegate y que tiene una propiedad de temporizador):

ApplicationDelegate.timer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(updateModel:) userInfo:str repeats:YES]; 
[[NSRunLoop currentRunLoop] addTimer:ApplicationDelegate.timer forMode:NSRunLoopCommonModes]; 

Opción dos:

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(updateModel:) userInfo:str repeats:YES]; 
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; 
+0

sorry ab el error en la publicación ... Lo he editado para reflejar la forma en que lo estoy haciendo. Estoy usando la segunda forma que mencionaste ... Todavía no está funcionando. – inforeqd

+20

La segunda forma es incorrecta. Está intentando agregar el temporizador dos veces. 'scheduledTimerWithTimeInterval: ...' ya ha agregado el temporizador. Asegúrate de ejecutar esto en el hilo principal. –

+0

¿hay alguna forma de averiguar en qué subproceso se está agregando el temporizador? Creo que es el hilo principal que lo estoy agregando a ... – inforeqd

5

Esta línea tiene varios problemas:

[[NSRunLoop currentRunLoop] addTimer:ApplicationDelegate.timer forMode:NSRunLoopCommonModes]; 

En primer lugar, no debe ser requerido en absoluto. -scheduledTimerWithTimeInterval:... ya agrega el temporizador al runloop. No necesita agregarlo nuevamente.

En segundo lugar, la variable local timer no está relacionada con la propiedad ApplicationDelegate.timer (que presumiblemente es nil en este momento).

Si está hablando con el delegado de la aplicación tanto que ha creado algo llamado ApplicationDelegate (¿una macro global?), Está hablando demasiado. El delegado de la aplicación es el delegado de la aplicación; ayuda en la aplicación de inicio y detención y respuesta a eventos del sistema. El delegado de la aplicación no es un lugar para almacenar variables globales. Un temporizador definitivamente no es el tipo de cosa que obtendrías de otro objeto en cualquier caso.

+0

disculpa por el error en la publicación ... Lo he editado para reflejar la forma en que lo estoy haciendo ... Todavía no está funcionando. Acerca de su comentario sobre el uso del delegado de la aplicación. Tengo un modelo que creo después de analizar una respuesta del servicio web. Tengo que conservar el modelo para todas las vistas en la aplicación. Por lo tanto, creo que el modelo debe ser retenido por el delegado de la aplicación; de lo contrario, no estoy seguro de dónde más puedo guardarlo para todas las vistas. – inforeqd

+1

Puede pasar el modelo a los controladores de vista cuando los construye, o puede colocar los objetos de modelo en un singleton. No debe colgarlos en el delegado de la aplicación. Esto hace que la reutilización de código sea muy difícil y complica al delegado de la aplicación (que tiene su propia función para realizar datos no relacionados con el almacenamiento). –

8

cojo el mismo problema, yo fuego temporizador en la cola principal para resolverlo:

[NSURLConnection sendAsynchronousRequest:request queue:_operationQueue 
    completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){ 
     [self loopUpUpdateStart]; 
}]; 

-(void)loopUpUpdateStart{ 
    dispatch_async(dispatch_get_main_queue(), ^{ 

     _loopTimerForUpRevision = 
      NSTimer scheduledTimerWithTimeInterval: kNetworkLoopIntervalUpRev 
              target: self 
             selector: @selector(myCoolMethod) 
             userInfo: nil 
             repeats: YES]; 
     TRACE(@"Start Up updates"); 
    }); 
} 
105

también podría ser un problema de roscado:

si

[NSThread isMainThread] 

es falso entonces comenzar el temporizador como este:

dispatch_async(dispatch_get_main_queue(), ^{ 
     timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(tick:) userInfo:nil repeats:YES]; 
    }) 
+0

+1, gracias ... ¡esto funcionó! – Joe

+1

¡Gracias! ¿Puedes explicarme cuál es el problema del enhebrado? – JohnH

+4

El temporizador se ejecuta solo en el hilo principal (UI) correctamente. Si intenta iniciar el temporizador en otro hilo que el hilo principal, no se disparará. – tmanthey