I\'ve gone through the iBook from Apple, and couldn\'t find any definition of it:
Can someone explain the structure of dispatch_after
?
d
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.
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
}
}
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())
}
In Swift 5, use in the below:
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2, execute: closure)
// time gap, specify unit is second
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(2)) {
Singleton.shared().printDate()
}
// default time gap is second, you can reduce it
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
// just do it!
}
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")
}
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
}