我如何每分钟运行一个功能?
在JavaScript中,我可以执行类似setInterval
的操作,在Swift中存在类似的东西吗?
通缉输出:
Hello World每分钟一次......
答案 0 :(得分:155)
var helloWorldTimer = NSTimer.scheduledTimerWithTimeInterval(60.0, target: self, selector: Selector("sayHello"), userInfo: nil, repeats: true)
func sayHello()
{
NSLog("hello World")
}
请记住导入基金会。
斯威夫特4: var helloWorldTimer = Timer.scheduledTimer(timeInterval: 60.0, target: self, selector: #selector(ViewController.sayHello), userInfo: nil, repeats: true)
@objc func sayHello()
{
NSLog("hello World")
}
答案 1 :(得分:123)
在Swift 3中,您可以创建Timer
。如果针对iOS 10及更高版本,您可以使用基于块的再现,这简化了潜在的强引用周期,例如:
weak var timer: Timer?
func startTimer() {
timer?.invalidate() // just in case you had existing `Timer`, `invalidate` it before we lose our reference to it
timer = Timer.scheduledTimer(withTimeInterval: 60.0, repeats: true) { [weak self] _ in
// do something here
}
}
func stopTimer() {
timer?.invalidate()
}
// if appropriate, make sure to stop your timer in `deinit`
deinit {
stopTimer()
}
在Swift 2中,您创建了一个NSTimer
。如果你使用的是Swift 2,你很可能会使用10.0之前的iOS版本,在这种情况下你必须使用较旧的target
/ selector
模式:
weak var timer: NSTimer?
func startTimer() {
timer?.invalidate() // just in case you had existing `NSTimer`, `invalidate` it before we lose our reference to it
timer = NSTimer.scheduledTimerWithTimeInterval(60.0, target: self, selector: #selector(handleTimer(_:)), userInfo: nil, repeats: true)
}
func handleTimer(timer: NSTimer) {
// do something here
}
func stopTimer() {
timer?.invalidate()
}
// because this old target/selector approach will keep a strong reference
// to the `target`, if you want the timer to stop when the view controller
// is dismissed, you can't stop the timer in `deinit`, but rather have to
// detect the dismissing of the view controller using other mechanisms. Commonly,
// we used to detect the view disappearing, like below:
override func viewDidDisappear(animated: Bool) {
super.viewDidDisappear(animated)
stopTimer()
}
虽然NSTimer
通常是最好的,但为了完整起见,我应该注意你也可以使用调度计时器,这对于在后台线程上调度计时器很有用。使用调度计时器,因为它们是基于块的,所以只要您使用{{{{}}},就可以避免使用target
/ selector
旧NSTimer
模式的一些强大的参考周期挑战1}}参考。
所以,在Swift 3中:
weak
在Swift 2中:
var timer: DispatchSourceTimer?
func startTimer() {
let queue = DispatchQueue(label: "com.domain.app.timer") // you can also use `DispatchQueue.main`, if you want
timer = DispatchSource.makeTimerSource(queue: queue)
timer!.scheduleRepeating(deadline: .now(), interval: .seconds(60))
timer!.setEventHandler { [weak self] in
// do whatever you want here
}
timer!.resume()
}
func stopTimer() {
timer?.cancel()
timer = nil
}
deinit {
self.stopTimer()
}
有关详细信息,请参阅并发编程指南的Dispatch Sources部分中 Dispatch Source Examples 的创建计时器部分。 / em>的
答案 2 :(得分:16)
这里是NSTimer
答案的更新,对于Swift 3(其中NSTimer
被重命名为Timer
)使用闭包而不是命名函数:
var timer = Timer.scheduledTimer(withTimeInterval: 60, repeats: true) {
(_) in
print("Hello world")
}
答案 3 :(得分:11)
您可以使用NSTimer
var timer = NSTimer.scheduledTimerWithTimeInterval(60, target: self, selector: Selector("function"), userInfo: nil, repeats: true)
在选择器()中输入你的功能名称
答案 4 :(得分:7)
在swift 3.0中,GCD被重构:
let timer : DispatchSourceTimer = DispatchSource.makeTimerSource(flags: [], queue: DispatchQueue.main)
timer.scheduleRepeating(deadline: .now(), interval: .seconds(60))
timer.setEventHandler
{
NSLog("Hello World")
}
timer.resume()
当您需要在特定队列上发送时,这特别有用。此外,如果您计划将其用于用户界面更新,我建议调查CADisplayLink
,因为它与GPU刷新率同步。
答案 5 :(得分:6)
如果你能允许一段时间漂移,这是一个每分钟执行一些代码的简单解决方案:
private func executeRepeatedly() {
// put your code here
DispatchQueue.main.asyncAfter(deadline: .now() + 60.0) { [weak self] in
self?.executeRepeatedly()
}
}
只需运行executeRepeatedly()
一次,它就会每分钟执行一次。当拥有对象(self
)被释放时,执行停止。您还可以使用标志来指示执行必须停止。
答案 6 :(得分:0)
这是另一个版本 algrid's 的答案,有一个简单的方法来阻止它
@objc func executeRepeatedly() {
print("--Do something on repeat--")
perform(#selector(executeRepeatedly), with: nil, afterDelay: 60.0)
}
以下是如何启动和停止它的示例:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
executeRepeatedly() // start it
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
NSObject.cancelPreviousPerformRequests(withTarget: self) // stop it
}