gpt4 book ai didi

swift - Swift 中高效且一致的时序 (GCD)

转载 作者:行者123 更新时间:2023-11-28 10:40:17 25 4
gpt4 key购买 nike

关闭。这个问题需要details or clarity .它目前不接受答案。












想改进这个问题?通过 editing this post 添加详细信息并澄清问题.

3年前关闭。




Improve this question




我正在开发的健身应用程序要求每 0.1 秒将运动数据附加到一个数组中,但是,当应用程序处于后台或设备锁定时发生的节能过程意味着该精度会漂移多达一秒。

我了解传统计时器通常遵循概述的行为,因此一直在研究替代方法,特别是 GCD 计时器。 A tutorial written on Medium解释了一种这样的方法,但是,我无法成功执行该功能。

我在运行:

let t = RepeatingTimer(timeInterval: 0.1)
t.eventHandler = {
print("Timer Fired")
}
t.resume()

在我的 viewDidLoad 函数中,但无济于事 - 没有打印任何文本。
override func viewDidLoad() {}

我的完整代码如下:
import Foundation
import UIKit
import SystemConfiguration

class accelVController: UIViewController {
override func viewDidLoad() {
let t = RepeatingTimer(timeInterval: 0.1)
t.eventHandler = {
print("Timer Fired")
}
t.resume()
}
}



/// RepeatingTimer mimics the API of DispatchSourceTimer but in a way that prevents
/// crashes that occur from calling resume multiple times on a timer that is
/// already resumed (noted by https://github.com/SiftScience/sift-ios/issues/52
class RepeatingTimer {

let timeInterval: TimeInterval

init(timeInterval: TimeInterval) {
self.timeInterval = timeInterval
}

private lazy var timer: DispatchSourceTimer = {
let t = DispatchSource.makeTimerSource()
t.schedule(deadline: .now() + self.timeInterval, repeating: self.timeInterval)
t.setEventHandler(handler: { [weak self] in
self?.eventHandler?()
})
return t
}()

var eventHandler: (() -> Void)?

private enum State {
case suspended
case resumed
}

private var state: State = .suspended

deinit {
timer.setEventHandler {}
timer.cancel()
/*
If the timer is suspended, calling cancel without resuming
triggers a crash. This is documented here https://forums.developer.apple.com/thread/15902
*/
resume()
eventHandler = nil
}

func resume() {
if state == .resumed {
return
}
state = .resumed
timer.resume()
}

func suspend() {
if state == .suspended {
return
}
state = .suspended
timer.suspend()
}

}

如果有人可以就改进的在后台一致地执行代码的方法提出建议,或者可以帮助我实现包含的代码,我将不胜感激。

更新:
该应用程序本质上是基于跌倒检测,尽管有与之相关的位置元素。

它基于三个数组。

数组 a : 包含时间戳,以及加速度是否低于最小阈值(1),是否大于最大阈值(2),或者两者都不(0)。它本质上是一个寄存器,并且是 2D - [[timestamp, status]]

数组 b : 是循环 的结果数组 a 并查找状态值 1。如果找到,则将元素的时间戳(仅)附加到数组中(从 a b )。

数组 c : 当检查 2 秒时间段是否包含 1 后跟 2 的函数(来自 数组 b )时附加 : 的值。这被视为潜在的下跌。仅附加时间戳。

然后循环遍历阵列 c,并查看在 3 秒内跌倒后的不活动时间,这表明失去知觉并需要寻求帮助。

我很欣赏这种方法可能效率低下,并且不是最好的方法,但是,对 Swift 知之甚少,这对我来说似乎是最明显的,并且如果不考虑背景,则可以工作。我很高兴收到有关更合适方法的建议。注意到跌倒的行动和方法是 based off of this paper.

我的代码可以是 seen here .为调试打印的数量道歉。

最佳答案

这是错误的做法。 Core Motion 为运动处理器提供了一个高效的接口(interface),而您的应用程序不必不断地触发计时器。计时器不会在后台得到尊重,所以这种方法无论如何都行不通。您会在后台事件的短时间内看到一些漂移,但如果您再给它几分钟,您通常会发现您的应用程序完全停止生成计时器事件。

如果您想要的是加速度计事件,请设置 CMMotionManager.accelerometerUpdateInterval到你想要的 (0.1) 并调用 startAccelerometerUpdates(to:withHandler)来处理事件。不要忘记在您的应用功能中启用“后台模式:位置更新”。

也就是说,您通常不应该尝试在 Core Motion 层管理健身应用程序。 Apple 通过 HealthKit 的 HKWorkout 提供更强大和更高级的支持。 .不可否认,HealthKit 有一个非常烦人的 API,但它会将你直接连接到 iOS 已经用来跟踪锻炼的系统,所以你可以免费获得很多功能(特别是帮助解决很多复杂的过滤问题)。

关于swift - Swift 中高效且一致的时序 (GCD),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50775270/

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