在这种情况下,永远不会调用timerFunc()。我错过了什么?
class AppDelegate: NSObject, NSApplicationDelegate {
var myTimer: NSTimer? = nil
func timerFunc() {
println("timerFunc()")
}
func applicationDidFinishLaunching(aNotification: NSNotification?) {
myTimer = NSTimer(timeInterval: 5.0, target: self, selector:"timerFunc", userInfo: nil, repeats: true)
}
}
答案 0 :(得分:8)
我对卢克采用了类似的方法。 对于那些“私人方法”纯粹主义者来说,只有一个警告:
不要在Swift中私下进行回调。
如果你写:
private func timerCallBack(timer: NSTimer){
...
你会得到:
timerCallBack:]:发送到实例的无法识别的选择器...由于未捕获的异常'NSInvalidArgumentException'而终止应用程序
答案 1 :(得分:7)
除非您使用NSTimer.scheduledTimerWithTimeInterval
myTimer = NSTimer.scheduledTimerWithTimeInterval(5.0, target: self, selector: "timerFunc", userInfo: nil, repeats: true)
答案 2 :(得分:6)
正如Drewag和Ryan所指出的那样,你需要创建一个预定的计时器(或自己安排)最简单的创建它已经计划好了:
myTimer = NSTimer.scheduledTimerWithTimeInterval(5.0, target: self, selector: "timerFunc:", userInfo: nil, repeats: true)
您还需要更改timerFunc(和关联的选择器)的定义以获取参数并以'结束:'
func timerFunc(timer:NSTimer!) {
...
}
答案 3 :(得分:6)
适用于Swift 3
var timer = Timer.scheduledTimer(timeInterval: 0.01, target: self, selector: #selector(ViewController.updateTimer), userInfo: nil, repeats: true);
RunLoop.current.add(timer, forMode: RunLoopMode.commonModes)
答案 4 :(得分:5)
运行循环的Swift 3.0语法:
RunLoop.current.add(myTimer, forMode: .commonModes)
答案 5 :(得分:4)
这是一些代码,演示了如何在没有参数的情况下使用AND调用函数(延迟)。
在xCode(singleViewApplication)的新项目中使用它,并将代码放入标准的viewController中:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
NSTimer.scheduledTimerWithTimeInterval(2.0, target: self, selector: Selector("delayedFunctionWithoutParameter:"), userInfo: nil, repeats: false)
let myParameter = "ParameterStringOrAnyOtherObject"
NSTimer.scheduledTimerWithTimeInterval(4.0, target: self, selector: Selector("delayedFunctionWithParameter:"), userInfo: myParameter, repeats: false)
}
// SIMPLE TIMER - Delayed Function Call
func delayedFunctionWithoutParameter(timer : NSTimer) {
print("This is a simple function beeing called without a parameter passed")
timer.invalidate()
}
// ADVANCED TIMER - Delayed Function Call with a Parameter
func delayedFunctionWithParameter(timer : NSTimer) {
// check, wether a valid Object did come over
if let myUserInfo: AnyObject = timer.userInfo {
// alternatively, assuming it is a String for sure coming over
// if let myUserInfo: String = timer.userInfo as? String {
// assuming it is a string comming over
print("This is an advanced function beeing called with a parameter (in this case: \(myUserInfo)) passed")
}
timer.invalidate()
}
}
请注意,在任何情况下,您都应该使用参数(timer:NSTimer)实现延迟函数,以便能够使计时器无效(终止,结束)。使用passend“timer”,你也可以访问userInfo(在那里你可以放置任何Object,不仅包括String-Objects,还有数组和字典等集合类型)。
原始苹果文档说“” - >计时器将自身作为参数传递,因此该方法将采用以下模式: - (void)timerFireMethod:(NSTimer *)计时器 完全阅读 - > here
答案 6 :(得分:3)
由于这个帖子让我尝试将计时器放在RunLoop上(这解决了我的问题),我也发布了我的具体案例 - 谁知道这可能对某人有所帮助。
我的计时器是在app启动和初始化所有对象期间创建的。我的问题是,虽然它确实安排了计时器,但它仍然没有被解雇。我的猜测是,这是因为scheduledTimerWithTimeInterval
在启动App期间将计时器放在不同的RunLoop上。如果我只是初始化计时器然后使用NSRunLoop.mainRunLoop().addTimer(myTimer, forMode:NSDefaultRunLoopMode)
,它可以正常工作。
答案 7 :(得分:3)
使用swift3,您可以使用
运行它var timer: Timer?
func startTimer() {
if timer == nil {
timer = Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(self.loop), userInfo: nil, repeats: true)
}
}
func stopTimer() {
if timer != nil {
timer?.invalidate()
timer = nil
}
}
func loop() {
//do something
}
答案 8 :(得分:2)
要使用OP建议的方法来执行此操作,您需要将其添加到运行循环中:
myTimer = NSTimer(timeInterval: 5.0, target: self, selector:"timerFunc", userInfo: nil, repeats: true)
NSRunLoop.mainRunLoop().addTimer(myTimer, forMode:NSDefaultRunLoopMode)
文档还说目标应该采用参数,但没有它就能正常工作。
func timerFireMethod(timer: NSTimer) { }