我想在某个点暂停我的应用程序。换句话说,我希望我的应用程序执行代码,但在某一点上,暂停4秒,然后继续执行其余的代码。我该怎么做呢?

我用的是Swift。


当前回答

在Swift 4.2和Xcode 10.1中

你总共有4种方法来延迟。在这些选项中,首选选项1是在一段时间后调用或执行函数。sleep()是使用最少的情况。

选项1。

DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
    self.yourFuncHere()
}
//Your function here    
func yourFuncHere() {

}

第二个选项。

perform(#selector(yourFuncHere2), with: nil, afterDelay: 5.0)

//Your function here  
@objc func yourFuncHere2() {
    print("this is...")
}

选项3。

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

//Your function here  
@objc func yourFuncHere3() {

}

选项4。

sleep(5)

如果你想在一段时间后调用一个函数来执行一些东西,不要使用sleep。

其他回答

DispatchQueue.global(qos: .background).async {
    sleep(4)
    print("Active after 4 sec, and doesn't block main")
    DispatchQueue.main.async{
        //do stuff in the main thread here
    }
}

如果从UI线程调用,sleep会锁住你的程序,可以考虑使用NSTimer或分派计时器。

但是,如果你真的需要延迟当前线程:

do {
    sleep(4)
}

这使用了UNIX中的睡眠函数。

Using a dispatch_after block is in most cases better than using sleep(time) as the thread on which the sleep is performed is blocked from doing other work. when using dispatch_after the thread which is worked on does not get blocked so it can do other work in the meantime. If you are working on the main thread of your application, using sleep(time) is bad for the user experience of your app as the UI is unresponsive during that time. Dispatch after schedules the execution of a block of code instead of freezing the thread:

斯威夫特≥ 3.0

let seconds = 4.0
DispatchQueue.main.asyncAfter(deadline: .now() + seconds) {
    // Put your code which should be executed with a delay here
}

Swift≥5.5(异步):

func foo() async {
    try await Task.sleep(nanoseconds: UInt64(seconds * Double(NSEC_PER_SEC)))
    // Put your code which should be executed with a delay here
}

Swift < 3.0

let time = dispatch_time(dispatch_time_t(DISPATCH_TIME_NOW), 4 * Int64(NSEC_PER_SEC))
dispatch_after(time, dispatch_get_main_queue()) {
    // Put your code which should be executed with a delay here
}

作为之前建议的选项的替代解决方案,您可以使用基于DispatchGroup类的延迟,它被设计为同步多个异步任务的执行:

print("Start")
print(Date())

let delay = DispatchTimeInterval.seconds(3)
let group = DispatchGroup()
group.enter()
_ = group.wait(timeout: .now() + delay)

print("Finish")
print(Date())

其中,enter()方法用于显式地指示组代码的执行已经开始,wait(timeout:)方法用于等待组任务完成。当然,在本例中,这种情况永远不会发生,为此指定了一个超时,它等于所需的延迟。

使用它作为现成的帮手非常方便:

public class DispatchWait {
    private init () { }
    
    public static func `for` (_ interval: DispatchTimeInterval) {
        let group = DispatchGroup()
        group.enter()
        _ = group.wait(timeout: .now().advanced(by: interval))
    }
}

使用DispatchWait的示例:

print("Start")
print(Date())

DispatchWait.for(.seconds(3))

print("Finish")
print(Date())

不幸的是,我不能说这个延迟的准确性是多少,以及wait(timeout:)方法允许在指定的延迟之后继续执行程序的概率是多少。

此外,此解决方案允许您延迟当前队列中的代码,而不必在单独的闭包中执行它。

你可以创建扩展来轻松使用延迟函数(语法:Swift 4.2+)

extension UIViewController {
    func delay(_ delay:Double, closure:@escaping ()->()) {
        DispatchQueue.main.asyncAfter(
            deadline: DispatchTime.now() + Double(Int64(delay * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC), execute: closure)
    }
}

如何在UIViewController中使用

self.delay(0.1, closure: {
   //execute code
})