Swift:我可以加减 `dispatch_time_t` 变量吗?
Swift: can I add and subtract `dispatch_time_t` variables?
我需要在 iOS 和 Swift 中做一些时间计算。
我必须使用 dispatch_walltime
。我希望这可以被视为公理化。在时间数学方面,我想我可能会得到 "just use NSDate
," 的回应,但请相信:我一定会 dispatch_walltime
.
现在,很明显为什么有人会建议 NSDate
,因为当您使用 NSTimeInterval
和 NSDate
等好东西时,制作自定义时间戳并进行比较非常容易他们并做各种时间数学。
但我必须使用 dispatch_time_t
,具体来说 dispatch_walltime
是这样创建的:
//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)
稍后我需要以各种方式使用该参考时间。例如,我需要获取参考时间和它恰好是的任何时间之间的时间间隔。
我正在尝试以与 NSTimeInterval
相同的方式进行此操作,换句话说,制作一个新的并从中减去旧的:
//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
这行得通吗?
简短的回答是:没有。该代码将崩溃。
更好的答案是:不,但可以做到,而且到头来也没什么不同。
我自己在 Playground 上做了一些调查,学到了一些有趣的东西,我相信我找到了正确的方法。
我将我的整个 Playground 粘贴到这里,以便其他人可以复制粘贴它并弄清楚如何进行他们自己的 dispatch_time
数学运算。
代码中标有 //********* 的注释表示我学到的关键内容。
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's 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()
我需要在 iOS 和 Swift 中做一些时间计算。
我必须使用 dispatch_walltime
。我希望这可以被视为公理化。在时间数学方面,我想我可能会得到 "just use NSDate
," 的回应,但请相信:我一定会 dispatch_walltime
.
现在,很明显为什么有人会建议 NSDate
,因为当您使用 NSTimeInterval
和 NSDate
等好东西时,制作自定义时间戳并进行比较非常容易他们并做各种时间数学。
但我必须使用 dispatch_time_t
,具体来说 dispatch_walltime
是这样创建的:
//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)
稍后我需要以各种方式使用该参考时间。例如,我需要获取参考时间和它恰好是的任何时间之间的时间间隔。
我正在尝试以与 NSTimeInterval
相同的方式进行此操作,换句话说,制作一个新的并从中减去旧的:
//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
这行得通吗?
简短的回答是:没有。该代码将崩溃。
更好的答案是:不,但可以做到,而且到头来也没什么不同。
我自己在 Playground 上做了一些调查,学到了一些有趣的东西,我相信我找到了正确的方法。
我将我的整个 Playground 粘贴到这里,以便其他人可以复制粘贴它并弄清楚如何进行他们自己的 dispatch_time
数学运算。
代码中标有 //********* 的注释表示我学到的关键内容。
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's 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()