- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
当系统时钟改变时,是否有运行代码的方法?
例如:当时钟增加一分钟时,运行 print(systemtime)
,我将当前时间存储在该变量中。
这只是为了我自己的测试目的,现在我有一个每分钟重复一次的计时器,获取当前时间并打印它。
但是,我正在寻找一种方法来在 iOS 中打印
时间到控制台的确切时间。
在更一般的意义上,一种在 iOS 时钟更改时触发运行代码的方法。
最佳答案
一句话,没有。 iOS 上的实时时钟具有亚微秒精度。它使用 double 来报告自 iOS“纪元日期”以来的小数秒时间。
在任意时间间隔(60 秒,秒)调用函数不是系统函数。
也就是说,您可以设置一个 CADisplayLink
(低开销计时器)同步到屏幕刷新,并且当时间在一分钟变化的某个阈值内时“( fmod(NSdate.timeIntervalSinceReferenceDate, 60) < 0.02
,比方说)您可以将消息记录到控制台。您需要使用阈值,因为您设置的任何间隔可能不会恰好出现在所需的标记上。
正如马特在下面的评论中指出的那样,CADisplayLink
可能会导致设备 CPU“过热”并比预期更快地耗尽电池电量。
如果您不需要毫秒精度,那么做一些数学计算来计算下一分钟的间隔并在适当的延迟后启动重复计时器可能是一个很好的折衷方案。像这样:
var timer: Timer?
func startMinuteTimer() {
let now = Date.timeIntervalSinceReferenceDate
let delayFraction = trunc(now) - now
//Caluclate a delay until the next even minute
let delay = 60.0 - Double(Int(now) % 60) + delayFraction
DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
self.timer = Timer.scheduledTimer(withTimeInterval: 60, repeats: true) {
timer in
//Put your code that runs every minute here.
}
}
}
NSTimer(定时器,在 Swift 3 中)的分辨率应该在 1/50 秒左右,因此代码应该使您的更新在目标时间的大约 0.02 秒内。
此外,任何时候您的应用程序变为非事件状态然后再次事件时,您都必须终止上述计时器并重新启动它,因为它会在您的应用程序未运行时暂停并且它不会被同步以启动甚至分钟。
正如我在回答的评论中所指出的,上面的代码在开始执行后的第一分钟内将无法触发。假设您的类中有一个函数 timeFunction 希望每分钟运行一次,您可以像这样修复它:
DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
self.timeFunction() //Call your code that runs every minute the first time
self.timer = Timer.scheduledTimer(withTimeInterval: 60, repeats: true) {
timer in
self.timeFunction() //Call your code that runs every minute.
}
}
我在一个示例 iOS 应用程序中使用了上述代码,发现如果您暂停该应用程序(将其切换到后台),则计时器将按预期停止触发。当您恢复您的应用程序时,计时器几乎立即触发,与“即时”时间不同步。然后它会在下一个即时时间再次出现。
为了避免在收到恢复调用时的关闭时间调用,您必须监听挂起和恢复事件,在挂起事件上使您的计时器无效,并在恢复事件上重新创建您的计时器。 (如果不将您的应用程序设置为在后台运行,则无法让它在后台或手机被锁定时每分钟持续触发。)
这是一个来自工作“单一 View ”应用程序的 View Controller 代码,它完成了所描述的一切:为 willResignActiveNotification 和 didBecomeActiveNotification 添加观察者,启动单次计时器以与分钟的变化同步,然后是重复计时器每一分钟。它有代码在每次计时器触发时将时间显示到标签上,并在每次更新时将时间附加到 TextView ,以便您可以看到行为,并记录暂停/恢复事件。
它有两个导出:
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var timeLabel: UILabel!
@IBOutlet weak var timeTextView: UITextView!
weak var timer: Timer?
var observer1, observer2: Any?
lazy var timeFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "HH:mm.ss.SSS"
return formatter
}()
func appendStringToLog(string: String) {
let newTimeLogText = timeTextView.text + "\n" + string
timeTextView.text = newTimeLogText
}
func timeFunction() {
let timeString = timeFormatter.string(from: Date())
timeLabel.text = timeString
appendStringToLog(string: timeString)
print(timeString)
}
func startMinuteTimer() {
let now = Date.timeIntervalSinceReferenceDate
let delayFraction = trunc(now) - now
//Caluclate a delay until the next even minute
let delay = 60.0 - Double(Int(now) % 60) + delayFraction
//First use a one-shot timer to wait until we are on an even minute interval
self.timer = Timer.scheduledTimer(withTimeInterval: delay, repeats: false) { timer in
//The first time through, call the time function
self.timeFunction() //Call your code that runs every minute the first time
//Now create a repeating timer that fires once a minute.
self.timer = Timer.scheduledTimer(withTimeInterval: 60, repeats: true) {
timer in
self.timeFunction() //Call your code that runs every minute.
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
//Observe the willResignActiveNotification so we can kill our timer
observer1 = NotificationCenter.default.addObserver(forName: UIApplication.willResignActiveNotification, object: nil, queue: nil) { notification in
let string = "Suspending. Stopping timer at \(self.timeFormatter.string(from: Date()))"
print(string)
self.appendStringToLog(string: string)
self.timer?.invalidate()
}
//Observe the didBecomeActiveNotification so we can start our timer (gets called on app launch and on resume)
observer2 = NotificationCenter.default.addObserver(forName: UIApplication.didBecomeActiveNotification, object: nil, queue: nil) { notification in
let string = "Becoming active. Starting timer at \(self.timeFormatter.string(from: Date()))"
print(string)
self.appendStringToLog(string: string)
self.startMinuteTimer()
}
}
}
关于ios - 当时间(iOS 时钟)发生变化时,有什么方法可以运行代码吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40983102/
我尝试理解[c代码 -> 汇编]代码 void node::Check( data & _data1, vector& _data2) { -> push ebp -> mov ebp,esp ->
我需要在当前表单(代码)的上下文中运行文本文件中的代码。其中一项要求是让代码创建新控件并将其添加到当前窗体。 例如,在Form1.cs中: using System.Windows.Forms; ..
我有此 C++ 代码并将其转换为 C# (.net Framework 4) 代码。有没有人给我一些关于 malloc、free 和 sprintf 方法的提示? int monate = ee; d
我的网络服务器代码有问题 #include #include #include #include #include #include #include int
给定以下 html 代码,将列表中的第三个元素(即“美丽”一词)以斜体显示的 CSS 代码是什么?当然,我可以给这个元素一个 id 或一个 class,但 html 代码必须保持不变。谢谢
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
我试图制作一个宏来避免重复代码和注释。 我试过这个: #define GrowOnPage(any Page, any Component) Component.Width := Page.Surfa
我正在尝试将我的旧 C++ 代码“翻译”成头条新闻所暗示的 C# 代码。问题是我是 C# 中的新手,并不是所有的东西都像 C++ 中那样。在 C++ 中这些解决方案运行良好,但在 C# 中只是不能。我
在 Windows 10 上工作,R 语言的格式化程序似乎没有在 Visual Studio Code 中完成它的工作。我试过R support for Visual Studio Code和 R-T
我正在处理一些报告(计数),我必须获取不同参数的计数。非常简单但乏味。 一个参数的示例查询: qCountsEmployee = ( "select count(*) from %s wher
最近几天我尝试从 d00m 调试网络错误。我开始用尽想法/线索,我希望其他 SO 用户拥有可能有用的宝贵经验。我希望能够提供所有相关信息,但我个人无法控制服务器环境。 整个事情始于用户注意到我们应用程
我有一个 app.js 文件,其中包含如下 dojo amd 模式代码: require(["dojo/dom", ..], function(dom){ dom.byId('someId').i
我对“-gencode”语句中的“code=sm_X”选项有点困惑。 一个例子:NVCC 编译器选项有什么作用 -gencode arch=compute_13,code=sm_13 嵌入库中? 只有
我为我的表格使用 X-editable 框架。 但是我有一些问题。 $(document).ready(function() { $('.access').editable({
我一直在通过本教程学习 flask/python http://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-i-hello-wo
我想将 Vim 和 EMACS 用于 CNC、G 代码和 M 代码。 Vim 或 EMACS 是否有任何语法或模式来处理这种类型的代码? 最佳答案 一些快速搜索使我找到了 this vim 和 thi
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 想改进这个问题?更新问题,使其成为 on-topic对于堆栈溢出。 7年前关闭。 Improve this
这个问题在这里已经有了答案: Enabling markdown highlighting in Vim (5 个回答) 6年前关闭。 当我在 Vim 中编辑包含 Markdown 代码的 READM
我正在 Swift3 iOS 中开发视频应用程序。基本上我必须将视频 Assets 和音频与淡入淡出效果合并为一个并将其保存到 iPhone 画廊。为此,我使用以下方法: private func d
pipeline { agent any stages { stage('Build') { steps { e
我是一名优秀的程序员,十分优秀!