3

我正在尝试在文本输入字段上设置超时,该字段仅在用户停止输入后一秒钟实现内部代码。因此,当用户键入时,我会不断调用 cleartimeout 并重新启动 setTimeout。

我最初是在查看 Objective C 中的 performSelector 函数,但看起来没有 Swift 等效的函数。

然后我转向 Swift 中的 GCD 函数,寻找一种方法来执行它。

这是我想出的:

var delta: Int64 = 1 * Int64(NSEC_PER_SEC)
var time = dispatch_time(DISPATCH_TIME_NOW, delta)
dispatch_suspend(dispatch_get_main_queue())
dispatch_after(time, dispatch_get_main_queue(), {
    println("timeout")
});

dispatch_suspend 函数没有像我希望的那样工作。

也许调度功能在这里不合适?

4

1 回答 1

7

dispatch_after是一个很好的替代方案,performSelect:afterDelay:但我认为这些都不是你想要的(因为一旦你设置了它们,就没有办法阻止它们)。

如果您希望仅在空闲一秒钟后才调用代码块,那么我认为您想使用计时器(例如NSTimer很好,或者您可以使用调度计时器)。最重要的是,每次您获得键盘交互时,请查看是否有挂起的计时器,如果有,则使其无效,然后安排新的计时器。

因此,我可能倾向于在 Swift 3 中执行以下操作。例如,在 iOS 10 及更高版本中,您可以使用块再现:

weak var timer: Timer?

func resetTimer() {
    timer?.invalidate()
    timer = .scheduledTimer(withTimeInterval: 1.0, repeats: false) { [weak self] timer in
        // do whatever you want when idle after certain period of time
    }
}

或者,如果您需要支持没有基于块的计时器的早期 iOS 版本:

weak var timer: Timer?

func resetTimer() {
    timer?.invalidate()
    timer = .scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(handleIdleEvent(_:)), userInfo: nil, repeats: false)
}

func handleIdleEvent(_ timer: Timer) {
    // do whatever you want when idle after certain period of time
}

或者,在 Swift 2 中:

weak var timer: NSTimer?

func resetTimer() {
    timer?.invalidate()
    let nextTimer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: "handleIdleEvent:", userInfo: nil, repeats: false)
    timer = nextTimer
}

func handleIdleEvent(timer: NSTimer) {
    // do whatever you want when idle after certain period of time
}

顺便说一句,我不确定你的意图dispatch_suspend是什么,但不要暂停主队列。您永远不想做任何可能干扰主队列及时处理事件的事情(即,永远不要阻塞/暂停主队列)。

于 2014-11-07T19:38:41.277 回答