2012-06-28 8 views
20

Sono nuovo allo sviluppo iOS, ho un semplice obiettivo -c class "MoneyTimer.m" per il timer di esecuzione, da lì voglio aggiornare l'etichetta dell'interfaccia utente con il valore variabile del timer. Voglio sapere come accedere all'elemento dell'interfaccia utente dal thread non dell'interfaccia utente? Sto usando Xcode 4.2 e storyboarding.Come aggiornare un'etichetta UI da un thread non dell'interfaccia utente in iOS

In blackberry è sufficiente ottenere il blocco degli eventi per aggiornare l'interfaccia utente da un thread non dell'interfaccia utente.

//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

È possibile aggiornare ui da ogni thread principale, aggiornamento delle UI da thread in background crea solo problema. – rishi

risposta

3

La tua domanda non dà molte informazioni o dettagli, quindi è difficile sapere esattamente che cosa dovete fare (ad esempio, se c'è un problema di "filo" a tutti, ecc).

In ogni caso, supponendo che l'istanza MoneyTimer abbia un riferimento al ViewController corrente è possibile utilizzare performSelectorOnMainThread.

//

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

scusate per la mancanza di dettagli, infatti ho una classe Timer che eredita da NSObject, da lì voglio aggiornare un UILabel inserito come una proprietà in uno dei miei ViewController. Ora non sono in grado di accedere alla form UILabel my Timer. –

+0

Perché non riesci ad accedervi? Aggiungi una proprietà delegato alla tua classe Timer e imposta il viewController con cui vuoi comunicare come delegato quando crei l'istanza Timer. Quindi chiama un metodo sul delegato per aggiornare l'etichetta. Questo è un modello di progettazione iOS standard, utile per conoscerlo. E solo per divertimento, stai facendo altro lavoro nella classe Timer? Forse stai diventando troppo orientato agli oggetti ;-) –

2

che ho fatto qualcosa di identico in passato.

Ho usato una funzione per impostare il testo dell'etichetta:

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

e poi chiamato questa funzione sul filo principale con performSelectorOnMainThread

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

Supponendo che vive etichette nella stessa classe:

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

Questo è il modo più semplice e rapido per farlo:

- (void) countUpH{ 

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

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

    }]; 
} 

Se lo si fa in questo modo non è necessario passare a un altro metodo.

Spero che questo aiuti.

Sam

+0

Funziona alla grande! Grazie! : D –

+0

@ shoughton123, posso anche chiamare '[[NSOperationQueue mainQueue] addOperationWithBlock: ...' all'interno di un metodo che viene eseguito in background? Grazie – JFS

+0

In effetti puoi, mi dispiace per la risposta lenta! – shoughton123

2

Il modo corretto è questo:

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

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