By Kumar KL


2014-06-04 10:05:19 8 Comments

I've gone through the iBook from Apple, and couldn't find any definition of it:

Can someone explain the structure of dispatch_after?

dispatch_after(<#when: dispatch_time_t#>, <#queue: dispatch_queue_t?#>, <#block: dispatch_block_t?#>)

22 comments

@brindy 2014-06-04 20:59:38

Swift 3+

This is super-easy and elegant in Swift 3+:

DispatchQueue.main.asyncAfter(deadline: .now() + 4.5) {
    // ...
}

Older Answer:

To expand on Cezary's answer, which will execute after 1 nanosecond, I had to do the following to execute after 4 and a half seconds.

let delay = 4.5 * Double(NSEC_PER_SEC)
let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay))
dispatch_after(time, dispatch_get_main_queue(), block)

Edit: I discovered that my original code was slightly wrong. Implicit typing causes a compile error if you don't cast NSEC_PER_SEC to a Double.

If anyone can suggest a more optimal solution I'd be keen to hear it.

@David L 2014-07-19 14:05:48

I get a compiler error for a deprecated API with dispatch_get_current_queue(). I used dispatch_get_main_queue() instead.

@brindy 2014-07-19 14:22:48

@DavidL - thanks, dispatch_get_main_queue() is definitely what you should be using. Will update.

@μολὼν.λαβέ 2016-12-22 21:59:22

i tried this in a playground with swift 3 and it doesn't work

@brindy 2016-12-22 22:20:09

@GAlexander Works for me. Are you allowing the playground to execute indefinitely?

@μολὼν.λαβέ 2016-12-22 23:04:33

uhm, well no, i let run run for a couple of hours and still nothing printed. here's what i used. "import Dispatch import Darwin import CoreGraphics 'DispatchQueue.main.asyncAfter(deadline: .now() + 4.5) { print(" got here ") } "

@brindy 2016-12-23 07:36:09

@GAlexander ah - you have to explicitly tell the Playground to allow indefinite execution. See stackoverflow.com/a/33536290/73479

@pkamb 2019-06-11 18:38:21

You should move your Swift 3+ code to the top of the answer. Or even delete the old code.

@Vakas 2016-10-24 06:00:34

Simplest solution in Swift 3.0 & Swift 4.0 & Swift 5.0

func delayWithSeconds(_ seconds: Double, completion: @escaping () -> ()) {
    DispatchQueue.main.asyncAfter(deadline: .now() + seconds) { 
        completion()
    }
}

Usage

delayWithSeconds(1) {
   //Do something
}

@μολὼν.λαβέ 2016-12-22 22:02:34

doesn't work in playground

@tania_S 2017-12-13 10:34:47

This what I needed. Thank u so much !

@A.G 2016-02-16 09:18:44

1) Add this method as a part of UIViewController Extension.

extension UIViewController{
func runAfterDelay(delay: NSTimeInterval, block: dispatch_block_t) {
        let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC)))
        dispatch_after(time, dispatch_get_main_queue(), block)
    }
}

Call this method on VC:

    self.runAfterDelay(5.0, block: {
     //Add code to this block
        print("run After Delay Success")
    })

2)

performSelector("yourMethod Name", withObject: nil, afterDelay: 1)

3)

override func viewWillAppear(animated: Bool) {

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2), dispatch_get_main_queue(), { () -> () in
    //Code Here
})

//Compact Form

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2), dispatch_get_main_queue()) {
    //Code here
 }
}

@CrazyPro007 2018-05-19 16:35:40

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    // ...
});

The dispatch_after(_:_:_:) function takes three parameters:

a delay
a dispatch queue
a block or closure

The dispatch_after(_:_:_:) function invokes the block or closure on the dispatch queue that is passed to the function after a given delay. Note that the delay is created using the dispatch_time(_:_:) function. Remember this because we also use this function in Swift.

I recommend to go through the tutorial Raywenderlich Dispatch tutorial

@BlackRock 2018-09-10 14:29:52

In Swift 4

Use this snippet:

    let delayInSec = 1.0
    DispatchQueue.main.asyncAfter(deadline: .now() + delayInSec) {
       // code here
       print("It works")
    }

@ayaio 2018-10-26 10:13:09

This is already in other answers (brindy's, for example, or Rahul's)... same syntax...

@Rahul Singha Roy 2018-07-11 09:56:04

For multiple functions use this. This is very helpful to use animations or Activity loader for static functions or any UI Update.

DispatchQueue.main.asyncAfter(deadline: .now() + 0.9) {
            // Call your function 1
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
                // Call your function 2
            }
        }

For example - Use a animation before a tableView reloads. Or any other UI update after the animation.

*// Start your amination* 
self.startAnimation()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.9) {
                *// The animation will execute depending on the delay time*
                self.stopAnimation()
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
                    *// Now update your view*
                     self.fetchData()
                     self.updateUI()
                }
            }

@guillaume 2018-08-13 11:55:24

Upvote for inline ...(deadline: .now() + 0.9) {

@Sanjay Mali 2018-04-13 10:01:43

Delaying GCD call using asyncAfter in swift

let delayQueue = DispatchQueue(label: "com.theappmaker.in", qos: .userInitiated)
let additionalTime: DispatchTimeInterval = .seconds(2)

We can delay as **microseconds,milliseconds,nanoseconds

delayQueue.asyncAfter(deadline: .now() + 0.60) {
    print(Date())
}

delayQueue.asyncAfter(deadline: .now() + additionalTime) {
    print(Date())
}

@Suhit Patil 2018-04-12 10:17:40

Swift 3 & 4:

You can create a extension on DispatchQueue and add function delay which uses DispatchQueue asyncAfter function internally

extension DispatchQueue {
    static func delay(_ delay: DispatchTimeInterval, closure: @escaping () -> ()) {
        let timeInterval = DispatchTime.now() + delay
        DispatchQueue.main.asyncAfter(deadline: timeInterval, execute: closure)
    }
}

use:

DispatchQueue.delay(.seconds(1)) {
    print("This is after delay")
}

@Vlady Veselinov 2018-03-17 01:48:39

Swift 4 has a pretty short way of doing this:

Timer.scheduledTimer(withTimeInterval: 2, repeats: false) { (timer) in
    // Your stuff here
    print("hello")
}

@Hardeep Singh 2018-02-21 06:31:32

I always prefer to use extension instead of free functions.

Swift 4

public extension DispatchQueue {

  private class func delay(delay: TimeInterval, closure: @escaping () -> Void) {
    let when = DispatchTime.now() + delay
    DispatchQueue.main.asyncAfter(deadline: when, execute: closure)
  }

  class func performAction(after seconds: TimeInterval, callBack: @escaping (() -> Void) ) {
    DispatchQueue.delay(delay: seconds) {
      callBack()
    }
  }

}

Use as follow.

DispatchQueue.performAction(after: 0.3) {
  // Code Here
}

@Tim 2018-01-03 07:12:04

Now more than syntactic sugar for asynchronous dispatches in Grand Central Dispatch (GCD) in Swift.

add Podfile

pod 'AsyncSwift'

Then,you can use it like this.

let seconds = 3.0
Async.main(after: seconds) {
print("Is called after 3 seconds")
}.background(after: 6.0) {
print("At least 3.0 seconds after previous block, and 6.0 after Async code is called")
}

@ingconti 2018-01-17 21:54:25

Apple has given us all needed to use GCD in few lines. Why to bother with pods, workspace and so on? Simply read docs about @escaping and capturing. it is enough.

@Ankit garg 2017-03-30 10:38:55

This worked for me.

Swift 3:

let time1 = 8.23
let time2 = 3.42

// Delay 2 seconds

DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
    print("Sum of times: \(time1 + time2)")
}

Objective-C:

CGFloat time1 = 3.49;
CGFloat time2 = 8.13;

// Delay 2 seconds

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    CGFloat newTime = time1 + time2;
    NSLog(@"New time: %f", newTime);
});

@Senseful 2015-11-12 00:45:55

Apple has a dispatch_after snippet for Objective-C:

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(<#delayInSeconds#> * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    <#code to be executed after a specified delay#>
});

Here is the same snippet ported to Swift 3:

DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + <#delayInSeconds#>) {
  <#code to be executed after a specified delay#>
}

@Dschee 2016-06-09 17:23:06

Another helper to delay your code that is 100% Swift in usage and optionally allows for choosing a different thread to run your delayed code from:

public func delay(bySeconds seconds: Double, dispatchLevel: DispatchLevel = .main, closure: @escaping () -> Void) {
    let dispatchTime = DispatchTime.now() + seconds
    dispatchLevel.dispatchQueue.asyncAfter(deadline: dispatchTime, execute: closure)
}

public enum DispatchLevel {
    case main, userInteractive, userInitiated, utility, background
    var dispatchQueue: DispatchQueue {
        switch self {
        case .main:                 return DispatchQueue.main
        case .userInteractive:      return DispatchQueue.global(qos: .userInteractive)
        case .userInitiated:        return DispatchQueue.global(qos: .userInitiated)
        case .utility:              return DispatchQueue.global(qos: .utility)
        case .background:           return DispatchQueue.global(qos: .background)
        }
    }
}

Now you simply delay your code on the Main thread like this:

delay(bySeconds: 1.5) { 
    // delayed code
}

If you want to delay your code to a different thread:

delay(bySeconds: 1.5, dispatchLevel: .background) { 
    // delayed code that will run on background thread
}

If you prefer a Framework that also has some more handy features then checkout HandySwift. You can add it to your project via Carthage then use it exactly like in the examples above, e.g.:

import HandySwift    

delay(bySeconds: 1.5) { 
    // delayed code
}

@Himanshu Mahajan 2016-01-21 16:24:27

use this code to perform some UI related task after 2.0 seconds.

            let delay = 2.0
            let delayInNanoSeconds = dispatch_time(DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC)))
            let mainQueue = dispatch_get_main_queue()

            dispatch_after(delayInNanoSeconds, mainQueue, {

                print("Some UI related task after delay")
            })

Swift 3.0 version

Following closure function execute some task after delay on main thread.

func performAfterDelay(delay : Double, onCompletion: @escaping() -> Void){

    DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + delay, execute: {
       onCompletion()
    })
}

Call this function like:

performAfterDelay(delay: 4.0) {
  print("test")
}

@Daniel Galasko 2016-01-22 07:23:13

This is almost identical to the previous answers

@eharo2 2018-08-09 22:22:38

It seems that this answer was done early 2016, and is older than at least other 6 answers..

@Himanshu Mahajan 2016-11-03 10:50:54

Swift 3.0 version

Following closure function execute some task after delay on main thread.

func performAfterDelay(delay : Double, onCompletion: @escaping() -> Void){

    DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + delay, execute: {
       onCompletion()
    })
}

Call this function like:

performAfterDelay(delay: 4.0) {
  print("test")
}

@matt 2014-06-20 01:57:41

I use dispatch_after so often that I wrote a top-level utility function to make the syntax simpler:

func delay(delay:Double, closure:()->()) {
    dispatch_after(
        dispatch_time(
            DISPATCH_TIME_NOW,
            Int64(delay * Double(NSEC_PER_SEC))
        ),
        dispatch_get_main_queue(), closure)
}

And now you can talk like this:

delay(0.4) {
    // do stuff
}

Wow, a language where you can improve the language. What could be better?


Update for Swift 3, Xcode 8 Seed 6

Seems almost not worth bothering with, now that they've improved the calling syntax:

func delay(_ delay:Double, closure:@escaping ()->()) {
    let when = DispatchTime.now() + delay
    DispatchQueue.main.asyncAfter(deadline: when, execute: closure)
}

@Aviel Gross 2014-08-20 15:31:41

I just needed shortcut for the delay calculation, ended up with: func delayInSec(delay: Double) -> dispatch_time_t { return dispatch_time(DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC))) }

@Matt 2014-08-21 19:40:51

Would delay(0.0) { /*stuff*/ } (insert appropriate linebreaks) be a valid command if I wanted to do something on the main thread without any delay (such as modify the GUI)?

@matt 2014-08-21 21:38:21

@Matt You tell me. You're looking at the code. What's the problem? Or if you're in doubt, call dispatch_async onto the main thread yourself. Again, what's the problem?

@Glenn Howes 2014-09-07 20:42:02

I love this usage. Similarly, you can do: func onMainQueue(closure:()->()){ NSOperationQueue.mainQueue().addOperationWithBlock(closure) }

@matt 2014-10-01 21:12:24

It's not a bug and it has nothing to do with my delay function. And ->() is the same thing as ->Void isn't it? It's just a closure "feature". I run into this all the time with closures. Basically just don't write any one-line closures, because Swift will try to treat this as syntactic sugar for returning the result of that expression.

@agf119105 2014-10-05 21:18:44

@matt Thanks for this code. It was working fine, but now I am getting the error, "Cannot convert the expression's type (FloatLiteralConvertible, () -> () -> $T3)' to type 'FloatLiteralConvertible' - Do you have any ideas why? Thanks ...

@matt 2014-10-05 21:54:16

@agf119105 If you have just one line of code in the closure, add another line of code (e.g. return).

@Matt 2014-10-07 02:03:24

Methinks there are too many "matt"s in this thread...

@matt 2014-10-07 02:15:19

@Matt there can be only one...

@Gaston 2015-01-02 10:52:37

how could we weakify self here? is self strongly retained?

@matt 2015-01-02 15:14:08

@GastonM Irrelevant. Passing a function has of itself no memory management issues.

@Mike Taverne 2015-02-05 17:46:46

@matt - This is great, but forgive my ignorance: where do I put this code to make it a top-level function? Thanks.

@matt 2015-02-05 17:56:59

@MikeTaverne At top level! (Of a swift file.) apeth.com/swiftBook/ch01.html#_the_structure_of_a_swift_file

@Mike Taverne 2015-02-05 18:00:14

@matt - Got it. That was easy! I didn't realize this was possible. Thanks again.

@Yerk 2015-06-18 20:04:42

"A language where you can improve the language". I don't understand how defining a global function is improving the language, or why this isn't doable in C even. Maybe if you overload an operator ;) 1.0 ~~ { code...}

@Antzi 2015-08-04 12:58:14

You could make it even better with a 0 default value to the delay parameter. This way you can also write delay { //do stuff } If you just need the execution to happen later

@Nikolai Ruhe 2015-09-24 07:36:36

Not questioning the correctness of your answer—but isn't "I use dispatch_after so often" a code smell which would best be fought by not providing a convenience function?

@MikeG 2016-01-30 03:19:20

@matt If this was called on global queue would it be less accurate? Or can it be on any queue and maintain the same accuracy and precision as when called on main queue? Thanks

@Shmidt 2016-02-26 15:20:55

@matt It would be great to use NSTimeInterval typealias for Double in this case.

@gnasher729 2016-05-27 22:14:13

NikolaiRuhe: No "code smell", but a nasal problem. @MikeG: Actually, it would be more accurate on a background queue. On a background queue, you have multiple threads and one can start exactly when you ask. On the main queue, any task that is executing at the exact dispatch time will finish first.

@Martin R 2016-06-15 11:44:12

You can simplify it to let when = DispatchTime.now() + delay in Swift 3 :) – Btw, I wonder what the function parameters should be called in accordance with swift.org/documentation/api-design-guidelines. Perhaps delay(for:execute:) ?

@matt 2016-06-15 13:53:17

@MartinR Yes, thanks, I was just getting around to that. I don't understand what the migrator was thinking here... — I never liked closure but probably no one will ever see or use it, as they'll be using trailing closure syntax. And I like having no first parameter.

@Dan Rosenstark 2016-06-16 00:27:24

@NikolaiRuhe Hmmmm... I use a dispatch after .001 for do on the next run loop so as to let stuff get set up. In truth, that should be all handled by the viewDidDisappear and all those methods, but sometimes passing a block around so someone else can execute it turns into even more cumbersome code.

@rptwsthi 2016-08-14 21:25:49

DispatchQueue.main.asyncAfter(deadline: when, execute: closure), giver error that Dispatch Queue have no member asyncAfter

@matt 2016-08-15 00:06:12

@rptwsthi Did you read what I said? Xcode 8, seed 4. You have not updated to Xcode 8 seed 4 (or seed 5).

@Cody Weaver 2016-08-31 15:19:55

How would you go about stopping the closure from executing. I am trying to do like a timer and every second a UILabel updates but if a user touches a certain button then the timer goes away.

@matt 2016-08-31 16:22:53

@CodyWeaver Then use a timer. I've explained elsewhere how to write a cancelable timer using GCD.

@JW.ZG 2016-09-13 02:17:53

In Swift 3, @escaping must be explicitly written in the code?

@Cezary Wojcik 2014-06-04 10:19:25

A clearer idea of the structure:

dispatch_after(when: dispatch_time_t, queue: dispatch_queue_t, block: dispatch_block_t?)

dispatch_time_t is a UInt64. The dispatch_queue_t is actually type aliased to an NSObject, but you should just use your familiar GCD methods to get queues. The block is a Swift closure. Specifically, dispatch_block_t is defined as () -> Void, which is equivalent to () -> ().

Example usage:

let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(1 * Double(NSEC_PER_SEC)))
dispatch_after(delayTime, dispatch_get_main_queue()) {
    print("test")
}

EDIT:

I recommend using @matt's really nice delay function.

EDIT 2:

In Swift 3, there will be new wrappers for GCD. See here: https://github.com/apple/swift-evolution/blob/master/proposals/0088-libdispatch-for-swift3.md

The original example would be written as follows in Swift 3:

let deadlineTime = DispatchTime.now() + .seconds(1)
DispatchQueue.main.asyncAfter(deadline: deadlineTime) {
    print("test")
}

Note that you can write the deadlineTime declaration as DispatchTime.now() + 1.0 and get the same result because the + operator is overridden as follows (similarly for -):

  • func +(time: DispatchTime, seconds: Double) -> DispatchTime
  • func +(time: DispatchWalltime, interval: DispatchTimeInterval) -> DispatchWalltime

This means that if you don't use the DispatchTimeInterval enum and just write a number, it is assumed that you are using seconds.

@Bill 2014-06-05 01:37:29

Tip: Because the block is the final parameter to the function, you can use Swift's "trailing closure" syntax for extra readability: dispatch_after(1, dispatch_get_main_queue()) { println("test") }

@Hlung 2014-08-27 18:16:37

I think using the number 1 in dispatch_after(1, ... may cause a lot of confusion here. People will think it is a number of seconds, when it actually is nano-second. I suggest see @brindy 's answer on how to create this number properly.

@OemerA 2014-11-08 12:17:19

Please change 1 to dispatch_time(DISPATCH_TIME_NOW, Int64(1 * Double(NSEC_PER_SEC))) because it leads to confusion. People could think that you don't need to create a dispatch_time_t in Swift

@Andy Ibanez 2016-06-24 23:21:45

The Swift 3 version doesn't appear to be working. It complaints that Binary operator '+' cannot be applied to operands of type DispatchTime and '_' on the line let delayTime = DispatchTime.now() + .seconds(1.0)

@Andy Ibanez 2016-06-24 23:23:18

Rewriting it as DispatchTime.now() + 1.0 seems to be the only way to make it work (no need for .seconds)

@Cezary Wojcik 2016-06-24 23:41:52

Thanks - updated the answer. The issue was actually that DispatchTimeInterval.seconds has an associated value of Int, so let delayTime = DispatchTime.now + .seconds(1) works.

@ArVID220u 2016-08-01 20:21:48

As of Swift 3 beta 4, after is renamed to asyncAfter, and its parameter when is renamed to deadline.

@Cezary Wojcik 2016-08-01 20:24:23

Thanks - updated.

@μολὼν.λαβέ 2016-12-22 22:23:55

any reason why this won't work in playgrounds?

@Shawn 2017-04-26 03:24:46

.seconds needs a value of Int, if you require a double value, use .milliseconds instead. e.g. + .milliseconds(1500) is more swifty than + 1.5

@Mohammad Sadiq Shaikh 2016-07-14 05:33:05

In Swift 3.0

Dispatch queues

  DispatchQueue(label: "test").async {
        //long running Background Task
        for obj in 0...1000 {
            print("async \(obj)")
        }

        // UI update in main queue
        DispatchQueue.main.async(execute: { 
            print("UI update on main queue")
        })

    }

    DispatchQueue(label: "m").sync {
        //long running Background Task
        for obj in 0...1000 {
            print("sync \(obj)")
        }

        // UI update in main queue
        DispatchQueue.main.sync(execute: {
            print("UI update on main queue")
        })
    }

Dispatch after 5 seconds

    DispatchQueue.main.after(when: DispatchTime.now() + 5) {
        print("Dispatch after 5 sec")
    }

@Suragch 2016-05-16 06:24:58

Although not the original question by the OP, certain NSTimer related questions have been marked as duplicates of this question, so it is worth including an NSTimer answer here.

NSTimer vs dispatch_after

  • NSTimer is more high level while dispatch_after is more low level.
  • NSTimer is easier to cancel. Canceling dispatch_after requires writing more code.

Delaying a task with NSTimer

Create an NSTimer instance.

var timer = NSTimer()

Start the timer with the delay that you need.

// invalidate the timer if there is any chance that it could have been called before
timer.invalidate()
// delay of 2 seconds
timer = NSTimer.scheduledTimerWithTimeInterval(2.0, target: self, selector: #selector(delayedAction), userInfo: nil, repeats: false) 

Add a function to be called after the delay (using whatever name you used for the selector parameter above).

func delayedAction() {
    print("Delayed action has now started."
}

Notes

  • If you need to cancel the action before it happens, simply call timer.invalidate().
  • For a repeated action use repeats: true.
  • If you have a one time event with no need to cancel then there is no need to create the timer instance variable. The following will suffice:

    NSTimer.scheduledTimerWithTimeInterval(2.0, target: self, selector: #selector(delayedAction), userInfo: nil, repeats: false) 
    
  • See my fuller answer here.

@Waam 2014-08-04 13:55:28

matt's syntax is very nice and if you need to invalidate the block, you may want to use this :

typealias dispatch_cancelable_closure = (cancel : Bool) -> Void

func delay(time:NSTimeInterval, closure:()->Void) ->  dispatch_cancelable_closure? {

    func dispatch_later(clsr:()->Void) {
        dispatch_after(
            dispatch_time(
                DISPATCH_TIME_NOW,
                Int64(time * Double(NSEC_PER_SEC))
            ),
            dispatch_get_main_queue(), clsr)
    }

    var closure:dispatch_block_t? = closure
    var cancelableClosure:dispatch_cancelable_closure?

    let delayedClosure:dispatch_cancelable_closure = { cancel in
        if closure != nil {
            if (cancel == false) {
                dispatch_async(dispatch_get_main_queue(), closure!);
            }
        }
        closure = nil
        cancelableClosure = nil
    }

    cancelableClosure = delayedClosure

    dispatch_later {
        if let delayedClosure = cancelableClosure {
            delayedClosure(cancel: false)
        }
    }

    return cancelableClosure;
}

func cancel_delay(closure:dispatch_cancelable_closure?) {

    if closure != nil {
        closure!(cancel: true)
    }
}

Use as follow

let retVal = delay(2.0) {
    println("Later")
}
delay(1.0) {
    cancel_delay(retVal)
}

credits

Link above seems to be down. Original Objc code from Github

@HotJard 2015-06-05 20:34:34

The one performance feature that has performSelector:afterDelay is ability to cancel it. Only this solution covers the problem. Thanks

@matt 2015-11-28 22:52:15

@HotJard Note that performSelector:afterDelay: is now available in Swift 2, so you can cancel it.

@HotJard 2015-12-01 13:18:21

@matt but it's available only for NSObject, isn't it?

@matt 2015-12-01 16:43:30

@HotJard Sure but that's better than not having it at all. I see no issue there. However, just as with this answer, I had already compensated for its loss by writing a GCD-based cancelable timer (using a dispatch_source_t, because that's something you can cancel).

@MikeG 2016-02-05 22:44:40

how would I make this so that I can call delay(1.0) { cancel_delay(retVal) } from another method such as didSelectRowAtIndexPath...?

@nontomatic 2016-09-14 12:04:38

Thanks a lot, I've been using this up to Swift 2.3. Swift 3.0 compiler is complaining now, would be great if you updated your answer!

@garafajon 2014-11-11 05:23:29

Another way is to extend Double like this:

extension Double {
   var dispatchTime: dispatch_time_t {
       get {
           return dispatch_time(DISPATCH_TIME_NOW,Int64(self * Double(NSEC_PER_SEC)))
       }
   }
}

Then you can use it like this:

dispatch_after(Double(2.0).dispatchTime, dispatch_get_main_queue(), { () -> Void in
            self.dismissViewControllerAnimated(true, completion: nil)
    })

I like matt's delay function but just out of preference I'd rather limit passing closures around.

Related Questions

Sponsored Content

19 Answered Questions

[SOLVED] #pragma mark in Swift?

  • 2014-06-03 14:05:56
  • Arbitur
  • 205841 View
  • 880 Score
  • 19 Answer
  • Tags:   swift

32 Answered Questions

[SOLVED] Split a String into an array in Swift?

16 Answered Questions

[SOLVED] How to call Objective-C code from Swift

  • 2014-06-02 20:05:42
  • David Mulder
  • 263871 View
  • 904 Score
  • 16 Answer
  • Tags:   objective-c swift

15 Answered Questions

[SOLVED] Swift for loop: for index, element in array?

  • 2014-06-04 03:19:21
  • metaphy
  • 365650 View
  • 696 Score
  • 15 Answer
  • Tags:   arrays swift

13 Answered Questions

[SOLVED] Bordered UITextView

  • 2010-04-15 16:31:57
  • Ali
  • 76072 View
  • 120 Score
  • 13 Answer
  • Tags:   ios quartz-core

13 Answered Questions

[SOLVED] How do I write dispatch_after GCD in Swift 3, 4, and 5?

22 Answered Questions

[SOLVED] @selector() in Swift?

9 Answered Questions

[SOLVED] Swift Beta performance: sorting arrays

1 Answered Questions

Sponsored Content