Swift: can I add and subtract `dispatch_time_t` variables?

I need to do time math in iOS, with Swift.

I need to use dispatch_walltime

. I hope this can be considered axiomatic. Where is the math of the time, I think I'm most likely getting the answer "just use NSDate

", but please take it on faith: I have to dispatch_walltime

.

It is now clear why someone might suggest NSDate

, because when you use NSTimeInterval

and NSDate

, and this is good stuff, it's pretty easy to create your own timestamps, compare them, and do all kinds of time math.

But I have to use dispatch_time_t

, namely dispatch_walltime

, created like this:

//Get the timeInterval of now.
let nowInterval = NSDate().timeIntervalSince1970

//Make a timespec from it.
var nowStruct = timespec(tv_sec: Int(nowInterval), tv_nsec: 0)

//Make a walltime definition from that.
let referenceWalltime = dispatch_walltime(&nowStruct, 0)

      

Later I need to use this link time in various ways. For example, I need to get the time interval between the checkout time and the time it will happen.

I'm trying to do it the same way I do with NSTimeInterval

, in other words, make a new one and subtract the old one from it:

//Repeat everything from before to make a new wall time.
let newNowInterval = NSDate().timeIntervalSince1970
var newNowStruct = timespec(tv_sec: Int(newNowInterval), tv_nsec: 0)
let newWalltime = dispatch_walltime(& newNowStruct, 0)

//Time math a la NSTimeInterval to find the interval:
let walltimeInterval = newWalltime - referenceWalltime

      

Will this work?

+3


source to share


1 answer


The short answer is no. This code will work.

The best answer is no, but it can be done and it's not all that is different in the end.

I did some research on my own in the playground and learned some interesting things and I believe I figured out the right way to do it.



I am pasting my entire playground here so others can copy it and figure out how to do their own math dispatch_time

.

The comments marked with // ********* in the code denote key things that I've learned.

import UIKit
import XCPlayground
XCPSetExecutionShouldContinueIndefinitely(continueIndefinitely: true)

public class IntervalMaker {

    var referenceWalltime: dispatch_time_t = 0
    var newWalltime: dispatch_time_t = 0
    var walltimeInterval: dispatch_time_t = 0

    func scheduleWalltimeSequence () {
         let threeSeconds = Int64(NSEC_PER_SEC) * 3
         let now = walltimeNow()
         let dispatchTimeInThree = dispatch_time(now, threeSeconds)
         let dispatchTimeInSix = dispatch_time(now,
             2 * threeSeconds)
         setReferenceWalltimeToNow()
         dispatch_after(dispatchTimeInThree, dispatch_get_main_queue(),
             setNewWalltimeToNow)
         dispatch_after(dispatchTimeInSix,
             dispatch_get_main_queue(), dispatchBasedOnDispatchMath)
    }

    func walltimeNow()->dispatch_time_t{
         let nowInterval = NSDate().timeIntervalSince1970
         var nowStruct = timespec(tv_sec: Int(nowInterval), tv_nsec: 0)
         return dispatch_walltime(&nowStruct, 0)
    }

    func setReferenceWalltimeToNow () {
         referenceWalltime = walltimeNow()
    }

    func setNewWalltimeToNow (){
         newWalltime = walltimeNow()
    }

    func dispatchBasedOnDispatchMath () {
         computeInterval() //Should be three seconds
         let nineTheWrongWay = referenceWalltime + (walltimeInterval * 3)
         let nineTheRightWay = dispatch_time(referenceWalltime,
             Int64(walltimeInterval) * 3)
         dispatch_after(nineTheWrongWay,
             dispatch_get_main_queue(), finalPrintln)
//********** THE ABOVE DOES NOT WORK CORRECTLY - prints 6 seconds later
         dispatch_after(nineTheRightWay,
             dispatch_get_main_queue(), finalPrintln)
//********** THE ABOVE WORKS CORRECTLY - prints 9 seconds later
    }

    func finalPrintln () {
        let now = walltimeNow()
        println("I should be printing nine seconds from reference time.")
        println("It actually \(referenceWalltime - now) nanoseconds after")
    }

    func computeInterval () {
        walltimeInterval = referenceWalltime - newWalltime
//********** dispatch_walltimes actually count backwards, and *CANNOT* be
//********** negative: writing `newWalltime - referenceWalltime` will crash
    }
}

 let intervaller = IntervalMaker()
 intervaller.scheduleWalltimeSequence()

      

+1


source







All Articles