- 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/
有没有办法在 .swift 文件(编译成 .swift 模块)中声明函数,如下所示: 你好.swift func hello_world() { println("hello world")
我正在尝试使用 xmpp_messenger_ios 和 XMPPFramework 在 iOS 上执行 MUC 这是加入房间的代码。 func createOrJoinRoomOnXMPP()
我想在我的应用程序上创建一个 3D Touch 快捷方式,我已经完成了有关快捷方式本身的所有操作,它显示正确,带有文本和图标。 当我运行这个快捷方式时,我的应用程序崩溃了,因为 AppDelegate
我的代码如下: let assetTag = Expression("asset_tag") let query2 = mdm.select(mdm[assetTag],os, mac, lastRe
我的 swift 代码如下所示 Family.arrayTuple:[(String,String)]? = [] Family.arrayTupleStorage:String? Family.ar
这是我的 JSON,当我读取 ord 和 uniq 数据时出现错误 let response2 : [String: Any] = ["Response":["status":"SUCCESS","
我想将 swift 扩展文件移动到 swift 包中。但是,将文件移动到 swift 包后,我遇到了这种错误: "Type 'NSAttributedString' has no member 'ma
使用CocoaPods,我们可以设置以下配置: pod 'SourceModel', :configurations => ['Debug'] 有什么方法可以用 Swift Package Manag
我正在 Xcode 中开发一个 swift 项目。我将其称为主要项目。我大部分都在工作。我在日期选择器、日期范围和日期数学方面遇到了麻烦,因此我开始了另一个名为 StarEndDate 的项目,其中只
这是 ObjectiveC 代码: CCSprite *progress = [CCSprite spriteWithImageNamed:@"progress.png"]; mProgressBar
我正在创建一个命令行工具,在 Xcode 中使用 Swift。我想使用一个类似于 grunt 的配置文件确实如此,但我希望它是像 Swift 包管理器的 package.swift 文件那样的快速代码
我假设这意味着使用系统上安装的任何 swift 运行脚本:#!/usr/bin/swift 如何指定脚本适用的解释器版本? 最佳答案 Cato可用于此: #!/usr/bin/env cato 1.2
代码说完全没问题,没有错误,但是当我去运行模拟器的时候,会出现这样的字样: (Swift.LazyMapCollection (_base:[ ] 我正在尝试创建一个显示报价的报价应用。 这是导入
是否可以在运行 Swift(例如 Perfect、Vapor、Kitura 等)的服务器上使用 RealmSwift 并使用它来存储数据? (我正在考虑尝试将其作为另一种解决方案的替代方案,例如 no
我刚开始学习编程,正在尝试完成 Swift 编程书中的实验。 它要求““编写一个函数,通过比较两个 Rank 值的原始值来比较它们。” enum Rank: Int { case Ace = 1 ca
在您将此问题标记为重复之前,我检查了 this question 它对我不起作用。 如何修复这个错误: error: SWIFT_VERSION '5.0' is unsupported, suppo
从 Xcode 9.3 开始,我在我的模型中使用“Swift.ImplicitlyUnwrappedOptional.some”包裹了我的字符串变量 我不知道这是怎么发生的,但它毁了我的应用程序! 我
这个问题在这里已经有了答案: How to include .swift file from other .swift file in an immediate mode? (2 个答案) 关闭 6
我正在使用 Swift Package Manager 创建一个应用程序,我需要知道构建项目的配置,即 Debug 或 Release。我试图避免使用 .xcodeproj 文件。请有人让我知道这是否
有一个带有函数定义的文件bar.swift: func bar() { println("bar") } 以及一个以立即模式运行的脚本foo.swift: #!/usr/bin/xcrun s
我是一名优秀的程序员,十分优秀!