Как ждать в Objective-C и Swift - PullRequest
       5

Как ждать в Objective-C и Swift

42 голосов
/ 08 августа 2011

Я хочу изменить текст UILabel через 2 секунды.

Я попытался установить для текста UILabel значение "Текст" , использовать sleep(2) и, наконец, изменить текст на "Другой текст" .

Но sleep(2) только замораживает приложение и «Другой текст» устанавливается без отображения «Текст» в течение 2 секунд.

Как я могу отобразить "Текст" в течение 2 секунд, а затем показать "Другой текст" ?

Ответы [ 8 ]

79 голосов
/ 08 августа 2013

Я знаю, что опоздал на эту вечеринку. Но я обнаружил, что люди не упоминают нить сна. Если вы используете GCD для вызова этой функции. Вы можете использовать:

[NSThread sleepForTimeInterval:2.0f];   

чтобы задержать нить на 2 секунды.

[self changeText: @"A text"];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        //Here your non-main thread.
        [NSThread sleepForTimeInterval:2.0f];   
        dispatch_async(dispatch_get_main_queue(), ^{
            //Here you returns to main thread.
            [self changeText: @"Another text"];
        });
    });

Изменить 2 (февраль 2015 г.):

Я думаю, что NSTimer - отличное решение. Мое решение просто дает еще один вариант для достижения цели NSTimer.

Пожалуйста, прочитайте: Как мне использовать NSTimer?

[NSTimer scheduledTimerWithTimeInterval:2.0
                                 target:self
                               selector:@selector(doSomethingWhenTimeIsUp:)
                               userInfo:nil
                                repeats:NO];

В классе вам нужен этот метод:

- (void) doSomethingWhenTimeIsUp:(NSTimer*)t {

        // YES! Do something here!!

}

Изменить 3 (май 2016 г.):

В Swift 2.0 вы можете использовать этот способ:

 NSTimer.scheduledTimerWithTimeInterval(2.0, 
                                         target: self, 
                                       selector: "doSomethingWhenTimeIsUp:", 
                                       userInfo: nil, 
                                        repeats: false)

Создает сущность NSTimer и автоматически добавляет таймер в NSRunLoop, связанный с NSThread, в котором создается таймер.

Изменить 4 (июнь 2016 г.):

В Swift 2.2 способ вызова select:

#selector(doSomethingWhenTimeIsUp(_:))

Итак, это что-то вроде:

  NSTimer.scheduledTimerWithTimeInterval(2.0,
                                      target: self,
                                      selector: #selector(doSomethingWhenTimeIsUp()),
                                      userInfo: nil,
                                      repeats: false)

Изменить 5 (октябрь 2016 г.):

В Swift 3 способ вызова select:

#selector(doSomethingWhenTimeIsUp)

Итак, это что-то вроде:

        Timer.scheduledTimer(timeInterval: 2.0,
                             target: self,
                             selector:#selector(doSomethingWhenTimeIsUp),
                             userInfo: nil,
                             repeats: false)

Тогда функция должна выглядеть так:

        @objc private func doSomethingWhenTimeIsUp(){
        // Do something when time is up
        }

Изменить 6 (май 2018 г.):

В Swift 4 мы можем сделать, как показано ниже.

    let delaySeconds = 2.0
    DispatchQueue.main.asyncAfter(deadline: .now() + delaySeconds) {
        doSomethingWhenTimeIsUp()
    }  

Тогда функция должна выглядеть следующим образом:

    private func doSomethingWhenTimeIsUp(){
        // Do something when time is up
        }
40 голосов
/ 08 августа 2011

Вы можете использовать

[self performSelector:@selector(changeText:) withObject:text afterDelay:2.0];

или, если вы хотите отображать его периодически, отметьте класс NSTimer.

28 голосов
/ 08 августа 2013

Grand Central Dispatch имеет вспомогательную функцию dispatch_after() для выполнения операций после задержки, которая может быть весьма полезной.Вы можете указать время ожидания перед выполнением и экземпляр dispatch_queue_t для запуска.Для выполнения в основном потоке (UI) можно использовать dispatch_get_main_queue().

double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
    // do something
});

В Swift 3 , приведенный выше пример можно записать в виде:

DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
    // do something
}
12 голосов
/ 08 августа 2011

Вы можете использовать NSTimer, вот так -

[NSTimer scheduledTimerWithTimeInterval:0.5 
                                 target:self 
                               selector:@selector(updateLabel:) 
                               userInfo:nil 
                                repeats:YES];

Определите другой метод updateLabel и выполните обновление там. Определите ваш timeInterval для удовлетворения ваших потребностей ...

Также установка repeats на YES гарантирует, что этот селектор будет выполняться каждые 0,5 секунды (в вышеописанном случае).

5 голосов
/ 08 августа 2011

Вы можете сделать это с помощью таймера, например,

   NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:4.0 target:self selector:@selector(eventToFire:) userInfo:nil repeats:YES]; // Fire every 4 seconds.

   ...

   - (void)eventToFire:(NSTimer*)timer {
      // Do Something
   }
2 голосов
/ 08 августа 2011

Вам нужно использовать таймер. Использование сна остановит всю вашу программу. Чек NSTimer

2 голосов
/ 08 августа 2011

Это потому, что представление не обновляется до конца цикла выполнения.Вместо использования снов попробуйте использовать NSTimer, чтобы установить определенное время для обновления представления.

0 голосов
/ 28 июня 2019

Следующий метод хорош.

Вы можете заменить свой

сон (1);

с

dispatch_semaphore_t semaphore = dispatch_semaphore_create (0); dispatch_semaphore_wait (семафор, dispatch_time (DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC));

...