2012-06-28 7 views
20

Jestem nowy w rozwoju iOS, mam zwykły obiektyw klasy -c "MoneyTimer.m" do uruchamiania licznika czasu, z którego chcę zaktualizować etykietę interfejsu użytkownika zmiana wartości zegara. Chcę wiedzieć, jak uzyskać dostęp do elementu interfejsu użytkownika z wątku non UI? Korzystam z Xcode 4.2 i tworzenia storyboardów.Jak zaktualizować etykietę interfejsu użytkownika z wątku innego niż UI w iOS

W blackberry po prostu poprzez uzyskanie blokady zdarzeń można aktualizować UI z wątku non 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

Można zaktualizować UI z wszystkimi głównym wątku, uaktualnianie UI z wątku tła tworzy jedyny problem. – rishi

Odpowiedz

3

Twoje pytanie nie daje dużo informacji lub szczegółu tak trudno jest dokładnie wiedzieć, co trzeba zrobić (na przykład, jeśli jest „wątek” problem w ogóle, itd.).

W każdym razie, zakładając, że twoja instancja MoneyTimer ma odniesienie do bieżącego viewController, możesz użyć performSelectorOnMainThread.

//

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

Przepraszam za brak szczegółów, W rzeczywistości mam klasy Timer, który dziedziczy z NSObject, stamtąd chcę zaktualizować UILabel umieszczony jako właściwość w jednym z moich ViewController. Teraz nie mam dostępu do UILabel z mojej klasy Timer. –

+0

Dlaczego nie możesz uzyskać do niego dostępu? Dodaj właściwość delegata do klasy Timer i ustaw kontroler viewController, z którym chcesz się komunikować, jako delegata podczas tworzenia instancji licznika czasu. Następnie wywołaj metodę na delegacie, aby zaktualizować etykietę. Jest to standardowy wzorzec systemu iOS - dobry do poznania go. I dla zabawy robisz inną pracę w klasie Timer? Być może stajesz się zbyt obiektowy ;-) –

2

Zrobiłem coś identycznego w przeszłości.

użyłem funkcji, aby ustawić tekst etykiety:

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

a następnie nazywa tę funkcję głównego wątku z performSelectorOnMainThread

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

Zakładając, który żyje na etykiecie w tej samej klasie:

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

Jest to najszybszy i najprostszy sposób, aby to zrobić:

- (void) countUpH{ 

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

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

    }]; 
} 

Jeśli robisz to w ten sposób, nie musisz przełączać się na inną metodę.

Mam nadzieję, że to pomoże.

Sam

+0

Działa świetnie! Dzięki! : D –

+0

@ shoughton123, czy mogę nawet wywołać '[[NSOperationQueue mainQueue] addOperationWithBlock: ...' w metodzie, która działa w tle? Dzięki – JFS

+0

Rzeczywiście możesz, przepraszam za powolną odpowiedź! – shoughton123

2

Właściwym sposobem jest taka:

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

    //Do any updates to your label here 
    yourLabel.text = newText; 
    }); 
} 
Powiązane problemy