2012-06-28 10 views
20

Soy nuevo en el desarrollo iOS, tengo el objetivo simple -c clase "MoneyTimer.m" para ejecutar el temporizador, de allí quiero actualizar la etiqueta UI con el valor cambiante del temporizador Quiero saber cómo acceder al elemento UI desde un subproceso que no sea UI? Estoy usando Xcode 4.2 y guiones gráficos.Cómo actualizar una etiqueta UI de un hilo que no sea UI en iOS

En blackberry simplemente al obtener el bloqueo de eventos, se puede actualizar la interfaz de usuario de la secuencia de comandos no UI.

//this the code from MyTimerClass 

{... 
    if(nsTimerUp == nil){ 

     nsTimerUp = [NSTimer scheduledTimerWithTimeInterval: 1.0 target:self selector:@selector(countUpH) userInfo:nil repeats: YES]; 
...} 

(void) countUpH { 

sumUp = sumUp + rateInSecH; 
**//from here i want to update the UI label ** 
... 
} 
+1

Puede actualizar la interfaz de usuario de todo hilo principal, la actualización de la interfaz de usuario a partir de hilos de fondo sólo crea problema. – rishi

Respuesta

3

Su pregunta no da mucha información o detalles por lo que es difícil saber exactamente lo que hay que hacer (por ejemplo, si hay un problema de "hilo" en absoluto, etc.).

En cualquier caso, suponiendo que su instancia de MoneyTimer tenga una referencia al viewController actual, puede usar performSelectorOnMainThread.

//

- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait; 
+0

lo siento por la falta de detalles, de hecho, tengo una clase de temporizador que hereda de NSObject, a partir de ahí quiero actualizar un UILabel colocado como una propiedad en uno de mis ViewController. Ahora no puedo acceder a UILabel desde mi clase Timer. –

+0

¿Por qué no puedes acceder a él? Agregue una propiedad delegada a su clase Timer y configure el viewController con el que desea comunicarse como delegado cuando cree la instancia Timer. Luego, llame a un método en el delegado para actualizar la etiqueta. Ese es un patrón de diseño de iOS estándar, es bueno conocerlo. Y solo por diversión, ¿estás haciendo otro trabajo en la clase Timer? Tal vez te estás orientando demasiado al objeto ;-) –

2

que he hecho algo idéntico en el pasado.

I utiliza una función para establecer el texto de la etiqueta:

- (void)updateLabelText:(NSString *)newText { 
    yourLabel.text = newText; 
} 

y luego llama esta función en el hilo principal con performSelectorOnMainThread

NSString* myText = @"new value"; 
[self performSelectorOnMainThread:(@selector)updateLabelText withObject:myText waitUntilDone:NO]; 
1

Suponiendo que la vida de la etiqueta en la misma clase:

if(nsTimerUp == nil){ 
     nsTimerUp = [NSTimer scheduledTimerWithTimeInterval: 1.0 target:self selector:@selector(countUpH) userInfo:nil repeats: YES]; 
    [self performSelectorOnMainThread:@selector(updateLabel) 
              withObject:nil 
             waitUntilDone:NO]; 

    } 

-(void)updateLabel { 
    self.myLabel.text = @"someValue"; 
} 
34

Esta es la manera más rápida y sencilla de hacerlo:

- (void) countUpH{ 

    sumUp = sumUp + rateInSecH; 
    //Accessing UI Thread 
    [[NSOperationQueue mainQueue] addOperationWithBlock:^{ 

     //Do any updates to your label here 
     yourLabel.text = newText; 

    }]; 
} 

Si lo hace de esta manera no tiene que cambiar a un método diferente.

Espero que esto ayude.

Sam

+0

¡Funciona muy bien! ¡Gracias! : D –

+0

@ shoughton123, ¿puedo llamar '' [[NSOperationQueue mainQueue] addOperationWithBlock: ... 'dentro de un método que se ejecuta en segundo plano? Gracias – JFS

+0

De hecho, puede, lo siento por la lenta respuesta! – shoughton123

2

La forma correcta es la siguiente:

- (void) countUpH { 
    sumUp = sumUp + rateInSecH; 
    //Accessing UI Thread 
    dispatch_async(dispatch_get_main_queue(), ^{ 

    //Do any updates to your label here 
    yourLabel.text = newText; 
    }); 
} 
Cuestiones relacionadas