c_b*_*oth 5 nstimer nsrunloop ios swift
以非常严格的时间安排重复任务的最佳方法是什么(对于音乐排序足够准确和可靠)?从 Apple 文档中,很明显 NSTimer 在这个意义上是不可靠的(即“计时器不是实时机制”)。我从 AudioKit 的AKPlaygroundLoop借用的一种方法在大约 4 毫秒内似乎是一致的(如果不是很准确),并且可能是可行的:
class JHLoop: NSObject{
var trigger: Int {
return Int(60 * duration) // 60fps * t in seconds
}
var counter: Int = 0
var duration: Double = 1.0 // in seconds, but actual loop is ~1.017s
var displayLink: CADisplayLink?
weak var delegate: JHLoopDelegate?
init(dur: Double) {
duration = dur
}
func stopLoop() {
displayLink?.invalidate()
}
func startLoop() {
counter = 0
displayLink = CADisplayLink(target: self, selector: "update")
displayLink?.frameInterval = 1
displayLink?.addToRunLoop(NSRunLoop.currentRunLoop(), forMode: NSRunLoopCommonModes)
}
func update() {
if counter < trigger {
counter++
} else {
counter = 0
// execute loop here
NSLog("loop executed")
delegate!.loopBody()
}
}
}
protocol JHLoopDelegate: class {
func loopBody()
}
Run Code Online (Sandbox Code Playgroud)
↑ 用我暂时尝试使用的实际类替换了代码。
作为参考,我希望制作一个多节奏鼓音序器,所以一致性是最重要的。我还需要能够实时平滑地修改循环,最好是循环周期。
有一个更好的方法吗?
您可以尝试使用 mach_wait_until() api。它\xe2\x80\x99s非常适合高精度定时器。我从这里稍微改变了苹果的例子。它在我的命令行工具项目中运行良好。在下面的代码片段中,我将main()方法从我的项目更改为startLoop(). 你也可以看到这个。\n希望有帮助。
static const uint64_t NANOS_PER_USEC = 1000ULL;\nstatic const uint64_t NANOS_PER_MILLISEC = 1000ULL * NANOS_PER_USEC;\nstatic const uint64_t NANOS_PER_SEC = 1000ULL * NANOS_PER_MILLISEC;\nstatic mach_timebase_info_data_t timebase_info;\n\nstatic uint64_t nanos_to_abs(uint64_t nanos) {\n return nanos * timebase_info.denom / timebase_info.numer;\n}\n\nfunc startLoop() {\n while(true) { // \n int64_t nanosec = waitSomeTime(1000); // each second\n NSLog(@"%lld", nanosec);\n update() // call needed update here \n }\n}\n\nuint64_t waitSomeTime(int64_t eachMillisec) {\n uint64_t start;\n uint64_t end;\n uint64_t elapsed;\n uint64_t elapsedNano;\n\n if ( timebase_info.denom == 0 ) {\n (void) mach_timebase_info(&timebase_info);\n }\n\n // Start the clock.\n start = mach_absolute_time();\n\n mach_wait_until(start + nanos_to_abs(eachMillisec * NANOS_PER_MILLISEC));\n\n // Stop the clock.\n end = mach_absolute_time();\n\n // Calculate the duration.\n elapsed = end - start;\n elapsedNano = elapsed * timebase_info.numer / timebase_info.denom;\n\n return elapsedNano;\n}\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
727 次 |
| 最近记录: |