如何将DispatchTimeInterval转换为NSTimeInterval(或Double)?

11

我需要从一个 DispatchTimeInterval 减去一个 NSTimeInterval(或者 Double)。

是否有一种标准的方法将 DispatchTimeInterval 转换为 NSTimeInterval


DispatchTimeInterval 用于 DispatchTime,而不是 (NS)Date 或 (NS)TimeInterval。你能详细说明一下为什么需要它吗?无论如何,DispatchTimeInterval 是一个枚举类型,将其转换为 Double 只需要简单的 switch/case 操作即可。 - Martin R
@MartinR,有一个计时器,使用DispatchTimeInterval设置,并且我在NSTimeInterval中测量经过的实际时间。我需要将两者相减以获得延迟。 - meaning-matters
3个回答

18

DispatchTimeInterval 是一个枚举类型:

public enum DispatchTimeInterval : Equatable {
    case seconds(Int)
    case milliseconds(Int)
    case microseconds(Int)
    case nanoseconds(Int)
    case never
}

您可以使用以下方式初始化DispatchTimeInterval

    let tenSeconds: DispatchTimeInterval = .seconds(10)
    let tenNanoseconds: DispatchTimeInterval = .nanoseconds(10)

从枚举类型中获取值,需要将该值与枚举类型中的case值匹配。
    if case .seconds(let value) = tenSeconds {
        print("DispatchTimeInterval is seconds \(value)")
    } else if case .nanoseconds(let value) = tenNanoseconds {
        print("DispatchTimeInterval is seconds \(value)")
    }

转换函数可能如下所示:

func toDouble(_ interval: DispatchTimeInterval) -> Double? {
        var result: Double? = 0

        switch interval {
        case .seconds(let value):
            result = Double(value)
        case .milliseconds(let value):
            result = Double(value)*0.001
        case .microseconds(let value):
            result = Double(value)*0.000001
        case .nanoseconds(let value):
            result = Double(value)*0.000000001

        case .never:
            result = nil
        }

        return result
    }

了解更多关于枚举的内容,请参见Apple文档。

更新:

创建 DispatchTimeInterval 的扩展。

extension DispatchTimeInterval {
    func toDouble() -> Double? {
        var result: Double? = 0

        switch self {
        case .seconds(let value):
            result = Double(value)
        case .milliseconds(let value):
            result = Double(value)*0.001
        case .microseconds(let value):
            result = Double(value)*0.000001
        case .nanoseconds(let value):
            result = Double(value)*0.000000001

        case .never:
            result = nil
        }

        return result
    }
}

11
一种简便的解决方案是创建一个TimeInterval扩展并在其中添加一个可失败初始化器,该初始化器带有一个DispatchTimeInterval参数。以下是Swift 5代码示例:
import Foundation

extension TimeInterval {

    init?(dispatchTimeInterval: DispatchTimeInterval) {
        switch dispatchTimeInterval {
        case .seconds(let value):
            self = Double(value)
        case .milliseconds(let value):
            self = Double(value) / 1_000
        case .microseconds(let value):
            self = Double(value) / 1_000_000
        case .nanoseconds(let value):
            self = Double(value) / 1_000_000_000
        case .never:
            return nil
        }
    }

}

使用方法:

let dispatchTimeInterval = DispatchTimeInterval.seconds(5)
let timeInterval = TimeInterval(dispatchTimeInterval: dispatchTimeInterval)
print(String(describing: timeInterval)) // Optional(5.0)

let dispatchTimeInterval = DispatchTimeInterval.milliseconds(30)
let timeInterval = TimeInterval(dispatchTimeInterval: dispatchTimeInterval)
print(String(describing: timeInterval)) // Optional(0.03)

3
一个非常简洁而简单的解决方案是这个(不需要使用switch语句)
extension DispatchTimeInterval {
  var nanoseconds: UInt64 {
    let now = DispatchTime.now()
    let later = now.advanced(by: self)
    return later.uptimeNanoseconds - now.uptimeNanoseconds
  }

  var timeInterval: TimeInterval {
    return Double(nanoseconds) / Double(NSEC_PER_SEC)
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接