2012-06-28 2 views
20

Я новичок в разработке iOS, у меня есть простой объект -c класс «MoneyTimer.m» для запуска таймера, оттуда я хочу обновить ярлык пользовательского интерфейса изменение значения таймера. Я хочу знать, как получить доступ к элементу пользовательского интерфейса из потока, отличного от UI? Я использую Xcode 4.2 и раскадровку.Как обновить ярлык пользовательского интерфейса из потока неинтерфейса в iOS

В ежевике, просто получив блокировку событий, можно обновить пользовательский интерфейс от нити пользовательского интерфейса.

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

Вы можете обновить пользовательский интерфейс из всех основных потока, обновление пользовательского интерфейса от фонового потока только создает проблемы. – rishi

ответ

3

Ваш вопрос не дает много информации или деталей, так что трудно точно знать, что вам нужно сделать (например, если есть «нить» проблема вообще, и т.д.).

Во всяком случае, если ваш экземпляр MoneyTimer имеет ссылку на текущий viewController, вы можете использовать performSelectorOnMainThread.

//

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

Извините за отсутствие деталей. На самом деле у меня есть класс Timer, который наследуется от NSObject, оттуда я хочу обновить UILabel, помещенный как свойство, в один из моих ViewController. Теперь я не могу получить доступ к типу Timer класса UILabel. –

+0

Почему вы не можете получить к нему доступ? Добавьте свойство делегата в свой класс Timer и установите viewController, с которым вы хотите общаться, как делегат при создании экземпляра Timer. Затем вызовите метод для делегата для обновления метки. Это стандартный шаблон дизайна для iOS - хорошо, чтобы узнать его. И просто для удовольствия, занимаетесь ли вы другой работой в классе Timer? Может быть, вы слишком объектно ориентированы ;-) –

2

Я сделал что-то идентичное в прошлом.

Я использовал функцию, чтобы установить текст метки:

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

, а затем называют эту функцию на главном потоке с performSelectorOnMainThread

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

Если предположить, что ярлык жизни в том же классе:

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

Это самый быстрый и простой способ сделать это:

- (void) countUpH{ 

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

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

    }]; 
} 

Если вы делаете это так, вам не нужно переключаться на другой метод.

Надеюсь, это поможет.

Сэм

+0

Отлично работает! Благодаря! : D –

+0

@ shoughton123, могу ли я даже назвать '[[NSOperationQueue mainQueue] addOperationWithBlock: ...' в методе, который работает в фоновом режиме? Спасибо – JFS

+0

Действительно, вы можете, извините за медленный ответ! – shoughton123

2

Правильный способ заключается в следующем:

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

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