gpt4 book ai didi

ios - NSTimer 在 firedate 之前触发

转载 作者:搜寻专家 更新时间:2023-11-01 07:25:21 26 4
gpt4 key购买 nike

我有下面的代码,它根据存储在 NSDefault 变量 checkOutTime 中的值初始化一个 NSTimer。

假设我将此变量中的时间更改为过去的时间(当前时间之前)并重新初始化计时器,它会自动触发并调用 ForceCheckOut() 回调方法。

我需要计时器仅在给定的触发日期触发。

func InitilizeAutoCheckOut(isExtendedCheckout:Bool)
{

let checkOutTime = self.defaults.valueForKey("checkOutTime") as! String

print(checkOutTime)



if !checkOutTime.isEmpty
{
let date = self.StringToDate(checkOutTime, IsExtendedCheckout: isExtendedCheckout)

print(date)

let autoCheckOutTimer = NSTimer(fireDate: date, interval: 24*60*60, target: self, selector: #selector(DashboardViewController.ForceCheckOut), userInfo: nil, repeats: true)
NSRunLoop.mainRunLoop().addTimer(autoCheckOutTimer, forMode: NSDefaultRunLoopMode)

}

}

最佳答案

正如在几个地方 (here is a good example) 中所解释的,NSTimerfireDate 实际上并不是计时器触发的日历日期时间。将其视为一种请求倒计时的机制更为准确。值得注意的是,NSTimer 不考虑时钟重置、背景等。它基本上计算一个数字,直到它应该触发,定期递减该数字,并在该数字 <= 0 时触发。更改本地时钟不会影响该数字,并且暂停进程(例如,通过后台运行应用程序)将导致倒计时从其当前值恢复,而不考虑它睡着的时间。这可以说是不直观的,因为 fireDate 强烈暗示“在这个日历日期开火”的契约(Contract),但 API 就是这样。

有了这些知识,您可以凭直觉知道您所看到的行为是预期的:如果您设置过去的日期,您实质上是在要求计时器从(负数)开始倒计时,因此计时器会立即识别满足触发条件(剩余时间 <= 0),并在被 runloop 唤醒后立即触发。

但即使没有这些知识,我也认为这种行为满足的期望多于它违背的期望。考虑:

The system reserves the right to apply a small amount of tolerance to certain timers regardless of the value of [tolerance]. -- NSTimer class ref.

如果您在未来很短的时间内安排一个计时器,则运行循环可能不会检查计时器,直到它的预定时间实际过去之后。通过触发定时器,即使时间已经过去,定时器或多或少会在指定时间触发,从而满足程序员的期望。

此外,您想要的行为会在管理计时器方面引入一系列复杂问题。如果您创建一个带有 future 触发日期的计时器,但在该触发日期过去之前不添加它会怎样?计时器应该触发还是不触发?当前的行为避免了该决定。

最简单的解决方案可能是在安排计时器之前检查触发日期,并且仅在触发日期满足您的条件时才将其添加到运行循环中:

let date = self.StringToDate(checkOutTime, IsExtendedCheckout: isExtendedCheckout)
let comparison = date.compare(NSDate())
guard comparison != .OrderedAscending else {
print("date \(date) has already passed. Not scheduling timer.")
return
}

关于ios - NSTimer 在 firedate 之前触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36744608/

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