Задать вопрос

Простой таймер на Objective C

Привет. Практикуюсь в Objective C, многие вещи не совсем очевидны.) Сейчас, мне не очень понятно, выполнение инструкций - оно не последовательное как в других ЯП (Python, PHP, Javascript), а как бы одновременное. И приходится идти на разные хитрости. Но сейчас речь не об этом.

- (IBAction)buttonStartTap:(id)sender {
    self.buttonStart.alpha = 0;
    for (InstructionModel * instruction in _=self.listOfInstructions){
        self.labelInstruction.text = [NSString stringWithFormat:@"%@", instruction.text];
        for (int i = 0; i < instruction.duration ; i++){
            [NSThread sleepForTimeInterval:1.0f];
            self.labelCounter.text = [NSString stringWithFormat:@"%d из %d", i, instruction.duration];
        }
    }
}


Собственно, что я имею. Массив listOfInstructions, каждый обьект массива имеет свойства; NSString * text, и int duration. Перебираю массив и по пути меняю текст label, каждый label сохраняет свой текст количество секунд обозначеное в duration.

Но вот незадача, текст не меняется.) Хотя NSLog показывает что перебор по массиву идет. Наверняка, это какая-то особенность
  • Вопрос задан
  • 5460 просмотров
Подписаться 4 Оценить 4 комментария
Решения вопроса 1
ManWithBear
@ManWithBear
Swift Adept, Prague
Так легче:
@interface MyViewController () {
    NSTimer *timer;
    int seconds;
    ...
} 
@property (weak, nonatomic) IBOutlet UILabel *timerLabel;
@end
...

- (void)viewDidLoad
{
    [super viewDidLoad];
    timer = [NSTimer scheduledTimerWithTimeInterval:1.0f  target:self selector:@selector(updateTimer:) userInfo:nil repeats:YES];
    [self.timerLabel setText:@"1:00"]
    seconds = 60;
}

- (void)updateTimer:(NSTimer *)theTimer {
    if (seconds>0) {
        seconds--;
        int min = seconds/60;
        int sec = seconds%60;
        [timerLabel setText:[NSString stringWithFormat:@"%01d:%02d",min,sec]];
    } else {
        [timer invalidate];
        NSLog(@"Timer end");
    }
}
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@agee
Ваша проблема напрямую связана с Вашим первым тезисом.
Вы либо вызываете sleepForTimeInterval в главном потоке, чем полностью вешаете юзер-интерфейс, либо наоборот, изменяете свойство text UI-объекта из второстепенного потока, что приводит к непредсказуемым результатам.
Попробуйте использовать второстепенный поток для цикла со sleep'ом, и оттуда меняйте свойство вызовом performSelectorOnMainThread.
И вообще, погуглите на тему потоков, это просто необходимо понимать.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы