- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我很难理解 DispatchSourceTimer 之间的主要区别, Timer和 asyncAfter (在我的例子中,调度一个需要每 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()
所有计时器的优缺点是什么?我什么时候应该在另一个之上使用一个?哪种定时器方式最有效?我想出了以下内容:
优点:
缺点:
优点:
缺点:
优点: - 不需要运行循环
缺点: - 无法取消(我认为)
还有更多的计时器吗?为什么有这么多定时器?我希望所有不同的计时器都有一些真正的区别,但我找不到它们。
这里有很多问题,您可以阅读。主要问题是:有哪些计时器可用,我应该在什么情况下使用哪些计时器以及为什么?
最佳答案
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/
我有一个计时器: let queue = DispatchQueue(label: "com.domain.app.timer") timer = DispatchSource.makeTimerSo
我有一个奇怪的行为,即我的应用程序在返回到之前的 View Controller 后崩溃了。我有一个显示配置文件 Controller ,然后我去编辑配置文件 Controller 。我在那里录制了一
我正在尝试使用 DispatchSourceTimer 在另一个线程上运行重复计时器。这段代码在 Playground 上运行良好,但在我的 iOS 应用程序中,它总是在 deinit 方法上崩溃(或
我不知道如何让调度计时器在 Swift 3.0 中重复工作。我的代码: let queue = DispatchQueue(label: "com.firm.app.timer",
我不知道如何让调度计时器在 Swift 3.0 中重复工作。我的代码: let queue = DispatchQueue(label: "com.firm.app.timer",
我有一个正在运行的 DispatchSourceTimer 是用以下方法创建的: self.timer = DispatchSource.makeTimerSource(flags: .init(ra
我很难理解 DispatchSourceTimer 之间的主要区别, Timer和 asyncAfter (在我的例子中,调度一个需要每 X 秒运行一次的任务,尽管了解定时器的差异可能对有用)(或者除
我不知道如何让调度计时器在 Swift 3.0 中重复工作。我的代码: let queue = DispatchQueue(label: "com.firm.app.timer",
我是一名优秀的程序员,十分优秀!