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
How to Wait in Objective-C and Swift
提问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
回答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_t
instance 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 updateLabel
and do the updation there. Define your timeInterval to suite your needs...
定义另一种方法updateLabel
并在那里进行更新。定义您的 timeInterval 以满足您的需求...
Also setting repeats
to YES
makes sure that this selector is executed every 0.5 seconds (in the above case).
还设置repeats
为YES
确保此选择器每 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
回答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));