gpt4 book ai didi

swift - DispatchSourceTimer、Timer 和 asyncAfter 之间的区别?

转载 作者:IT王子 更新时间:2023-10-29 05:13:19 27 4
gpt4 key购买 nike

我很难理解 DispatchSourceTimer 之间的主要区别, TimerasyncAfter (在我的例子中,调度一个需要每 X 秒运行一次的任务,尽管了解定时器的差异可能对有用)(或者除了列出的计时器?)。

Timer 需要在其启动所在的当前队列上有一个事件的运行循环。 DispatchSourceTimer 不需要它。 Timer 防止 CPU 进入空闲状态。这是否也适用于 DispatchSourceTimer/asyncAfter

在什么情况下 Timer 优于 DispatchSourceTimer/asyncAfter?当然还有它们之间的区别?

我想在我的应用程序中的私有(private)队列中每 15 秒安排一次工作。这意味着我必须使用 DispatchSourceTimer,因为我在一个不是主线程的队列中(或者向队列添加一个运行循环并使用 Timer)。但是,我什至一开始就没有看到使用 Timer 有任何好处。也许还有另一种操作,我可以在私有(private)队列上每 X 秒使用一次调度工作,这比 DispatchSourceTimer 更有效,但我没有找到更好的解决方案。

DispatchSourceTimer 是否比 Timer 更高效?还是应该使用 asyncAfter 进行自调用?

这是创建计时器的代码。

asyncAfter

DispatchQueue.global().asyncAfter(deadline: .now() + .seconds(2)) {
// Code
}

计时器

Timer.scheduledTimer(withTimeInterval: 1, repeats: false) { (_) in
// Code
}

DispatchSourceTimer

let timer = DispatchSource.makeTimerSource()

timer.schedule(deadline: .now() + .seconds(1))

timer.setEventHandler {
// Code
}

timer.activate()

所有计时器的优缺点是什么?我什么时候应该在另一个之上使用一个?哪种定时器方式最有效?我想出了以下内容:

计时器

优点:

  • 可以失效
  • 无需引用
  • 可以按计划停止。

缺点:

  • 防止 CPU 空闲
  • 需要在带有运行循环的队列上运行(否则什么也不会发生,甚至没有断言触发器...)

DispatchSourceTimer

优点:

  • 可以取消
  • 不需要运行循环

缺点:

  • 需要一个强引用,否则它会立即被释放

异步之后

优点: - 不需要运行循环

缺点: - 无法取消(我认为)

还有更多的计时器吗?为什么有这么多定时器?我希望所有不同的计时器都有一些真正的区别,但我找不到它们。

这里有很多问题,您可以阅读。主要问题是:有哪些计时器可用,我应该在什么情况下使用哪些计时器以及为什么?

最佳答案

Timer 是 NSTimer 的 Swift 桥接器,它可以追溯到 NeXTSTEP,远早于 Grand Central Dispatch (GCD) 和诸如 DispatchSourceTimer 之类的东西,直到 10.6(以 dispatch_source_set_timer 的形式)和 dispatchAfter (以 dispatch_after 的形式)。

NSTimer 基于运行循环,这是在 GCD 之前完成并发的主要方式。它是一个协作并发系统,主要设计为在单个内核上的单个线程上运行(尽管它可以扩展到多线程环境)。

虽然运行循环在 Cocoa 中仍然非常重要,但它不再是管理并发的主要方式,甚至不再是首选方式。自 10.6 以来,GCD 一直是越来越受欢迎的方法(尽管在 10.12 时间框架中添加基于 block 的 NSTimer API 是一个受欢迎的现代化)。

在 15 秒的范围内,效率差异是无关紧要的。也就是说,我不明白您的评论“定时器阻止 CPU 进入空闲状态”。我不相信那是真的。在等待 NSTimer 触发时,CPU 肯定仍会进入空闲状态。

我不会为了运行 NSTimer 而设置运行循环。您最好将其安排在主运行循环上,然后使用 DispatchQueue.async 在其他队列上执行实际工作。

一般来说,我会使用满足需求的最高级别的工具。随着时间的推移,这些是 Apple 可能会优化得最好的,而我所做的更改最少。例如,NSTimer 的触发日期会自动调整以提高能源效率。使用 DispatchSourceTimer,您可以控制 leeway 设置以获得相同的好处,但设置它取决于您(默认值为零,这对能量的影响最差)。当然,反之亦然。 DispatchSourceTimer 是最低级别并为您提供最多的控制权,因此如果您需要它,就可以使用它。

对于您的示例,我个人可能会使用 Timer 并将其作为 block 的一部分分派(dispatch)到专用队列。但是 DispatchSourceTimer 是完全合适的。

asyncAfter 确实是另一回事,因为它始终是一次性的。如果你想要一次性,那很好,但如果你想重复,它会改变事情。如果您只是在要重复的 block 中调用 asyncAfter,它将在您上次完成后 15 秒,而不是间隔 15 秒。随着时间的推移,前者往往会漂移得晚一些。设计问题是这样的:如果由于某种原因您的任务需要 5 秒才能完成,您是否希望下一次火灾事件在该事件结束后 15 秒发生,或者您希望每次火灾事件之间保持恒定的 15 秒?您的选择将决定哪个工具是正确的。

作为一个小提示,NSTimer 事件总是比它们计划的晚一点。有余地设置的GCD事件可以早一点也可以晚一点。实际上,没有“准时”这样的事情(那是一个零长度的时间段;你不会按时完成)。所以问题始终是你是否 promise 像 NSTimer 一样迟到,或者你可能像 GCD 一样有余地早。

关于swift - DispatchSourceTimer、Timer 和 asyncAfter 之间的区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55131532/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com