ios 如何在 Objective-C 和 Swift 中等待

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6983400/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 21:00:29  来源:igfitidea点击:

How to Wait in Objective-C and Swift

iosobjective-cswiftwaitperformselector

提问by jylee

I want to change my UILabel's text after 2 seconds.

我想UILabel在 2 秒后更改我的文本。

I tried setting my UILabel's text to "A text", and use sleep(2)and finally changing the text to "Another text".

我尝试将我UILabel的文本设置为"A text",并使用sleep(2)并最终将文本更改为"Another text"

But sleep(2)only freezes the app and "Another text"is set without displaying "A text"for 2 seconds.

sleep(2)只会冻结应用程序并设置“另一个文本”而不显示“A 文本”2 秒钟。

How may I display "A text"for 2 seconds and then show "Another text"?

如何显示“A 文本”2 秒钟,然后显示“另一文本”

采纳答案by Micha? Zygar

You can use

您可以使用

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

or if you want to display it periodically, check the NSTimerclass.

或者如果您想定期显示它,请检查NSTimer类。

回答by Yi Jiang

I know I am late to this party. But I found people haven't mention thread sleep. If you are using GCD to call that function. You can use :

我知道我参加这个聚会迟到了。但我发现人们没有提到线程睡眠。如果您使用 GCD 来调用该函数。您可以使用 :

[NSThread sleepForTimeInterval:2.0f];   

to delay the thread for 2 seconds.

将线程延迟 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"];
        });
    });

Edit 2 (Feb 2015):

编辑 2(2015 年 2 月):

I think the NSTimer is a great solution. My solution just giving another option to achieve the goal of NSTimer.

我认为 NSTimer 是一个很好的解决方案。我的解决方案只是提供了另一种选择来实现 NSTimer 的目标。

Please read: How do I use NSTimer?

请阅读:如何使用 NSTimer?

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

In the class, you need this method:

在课堂上,你需要这个方法:

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

        // YES! Do something here!!

}

Edit 3 (May 2016):

编辑 3(2016 年 5 月):

In Swift 2.0, you can use this way:

在 Swift 2.0 中,你可以这样使用:

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

It creates an NSTimer's entity and adds the timer automatically to the NSRunLoop associated with the NSThread in which the timer is created.

它创建一个 NSTimer 的实体,并自动将计时器添加到与创建计时器的 NSThread 关联的 NSRunLoop 中。

Edit 4 (Jun 2016):

编辑 4(2016 年 6 月):

In Swift 2.2, the way to invoke select is:

在 Swift 2.2 中,调用 select 的方式是:

#selector(doSomethingWhenTimeIsUp(_:))

So, it is something like:

所以,它是这样的:

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

Edit 5 (Oct 2016):

编辑 5(2016 年 10 月):

In Swift 3, the way to invoke select is:

在 Swift 3 中,调用 select 的方式是:

#selector(doSomethingWhenTimeIsUp)

So, it is something like:

所以,它是这样的:

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

Then, the func should looks like this:

然后,func 应该是这样的:

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

Edit 6 (May 2018):

编辑 6(2018 年 5 月):

In Swift 4, we can do as below way.

Swift 4 中,我们可以按照以下方式进行。

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

Then, the func should looks like this:

然后,func 应该是这样的:

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

回答by Mick MacCallum

Grand Central Dispatch has a helper function dispatch_after()for performing operations after a delay that can be quite helpful. You can specify the amount of time to wait before execution, and the dispatch_queue_tinstance to run on. You can use dispatch_get_main_queue()to execute on the main (UI) thread.

Grand Central Dispatch 有一个辅助功能,dispatch_after()用于在延迟后执行操作,这非常有用。您可以指定执行前要等待的时间量以及dispatch_queue_t要运行的实例。您可以使用dispatch_get_main_queue()在主(UI)线程上执行。

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
});

In Swift 3, the above example can be written as:

Swift 3 中,上面的例子可以写成:

DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
    // do something
}

回答by Srikar Appalaraju

You can use NSTimer, like so -

你可以NSTimer像这样使用-

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

Define another method updateLabeland do the updation there. Define your timeInterval to suite your needs...

定义另一种方法updateLabel并在那里进行更新。定义您的 timeInterval 以满足您的需求...

Also setting repeatsto YESmakes sure that this selector is executed every 0.5 seconds (in the above case).

还设置repeatsYES确保此选择器每 0.5 秒执行一次(在上述情况下)。

回答by George Johnston

You can accomplish this with a timer, e.g.

您可以使用计时器完成此操作,例如

   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
   }

回答by Dave

This is because the view isn't updated until the end of the runloop. Instead of using sleeps try using NSTimer to set a specific time to update the view.

这是因为视图直到 runloop 结束才会更新。不要使用 sleeps 尝试使用 NSTimer 设置特定时间来更新视图。

回答by Pepe

You need to use a timer. Using sleep will halt your entire program. Check NSTimer

您需要使用计时器。使用 sleep 会停止你的整个程序。检查NSTimer

回答by JateXu

The follow method is good.

下面的方法很好。

You can replace your

你可以更换你的

sleep(1);

睡眠(1);

with

dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC));

dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC));