I am currently working on a project and for a part of it I need to unhighlight a button after a set period of time. I decided to use dispatch_after
.
I have managed to get it working, but can someone please explain me how this line of code exactly works? I have been unable to understand how dispatch_after
exactly works.
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(1000 * Double(NSEC_PER_MSEC))), dispatch_get_main_queue()) {
self.redButton.highlighted = false
}
Let's break it down into multiple statements:
let when = dispatch_time(DISPATCH_TIME_NOW, Int64(1000 * Double(NSEC_PER_MSEC)))
let queue = dispatch_get_main_queue()
dispatch_after(when, queue) {
self.redButton.highlighted = false
}
dispatch_after()
enqueues the block for execution at a certain time
on a certain queue. In your case, the queue is the "main queue"
which is "the serial dispatch queue associated with the application’s main thread". All UI elements must be modified on the main thread only.
The when:
parameter of dispatch_after()
is a dispatch_time_t
which is documented as "a somewhat abstract representation of time".
dispatch_time()
is an utility function to compute that time value.
It takes an initial time, in this case DISPATCH_TIME_NOW
which
"indicates a time that occurs immediately", and adds an offset which
is specified in nanoseconds:
let when = dispatch_time(DISPATCH_TIME_NOW, Int64(1000 * Double(NSEC_PER_MSEC)))
NSEC_PER_MSEC = 1000000
is the number of nanoseconds per millisecond,
so
Int64(1000 * Double(NSEC_PER_MSEC))
is an offset of 1000*1000000 nanoseconds = 1000 milliseconds = one second.
The explicit type conversions are necessary because Swift does not
implicitly convert between types. Using Double
ensures that it
works also in cases like
let when = dispatch_time(DISPATCH_TIME_NOW, Int64(0.3 * Double(NSEC_PER_SEC)))
to specify an offset of 0.3 seconds.
Summary: Your code enqueues a block to be executed on the main thread in 1000 ms from now.
Update: See How do I write dispatch_after GCD in Swift 3 and 4? for how the syntax changed in Swift 3.