Der Fehler Sie bekommen hübsch obskur. Was es Ihnen zu sagen versucht, ist, dass Sie die ()
vom Ende Ihrer timerFired
in der #selector
entfernen sollten.
var timer = NSTimer(
timeInterval: 1.0,
target: self,
selector: #selector(TestTimer.timerFired),
userInfo: nil,
repeats: true)
Doch dies wird nicht der Code machen, wie Sie es arbeiten wollen - wie self
in der Timer-Erklärung bezieht sich auf den View-Controller, nicht der Timer. Ich würde Ihnen empfehlen, eine Wrapper-Klasse für NSTimer
zusammen mit einem Delegatenmuster zu erstellen, um zu erreichen, was Sie wollen.
sollten Sie beachten, dass the documentation states, dass Sie sollten nicht zu Unterklasse NSTimer
versuchen, so könnte man stattdessen so etwas tun:
// the protocol that defines the timerDidFire callback method
protocol TimerDelegate:class {
func timerDidFire(cumulativeTime:NSTimeInterval)
}
// your timer wrapper class
class TimerWrapper {
// the underlying timer object
weak private var _timer:NSTimer?
// the start date of when the timer first started
private var _startDate = NSDate()
// the delegate used to implement the timerDidFire callback method
weak var delegate:TimerDelegate?
// start the timer with a given firing interval – which could be a property
func startTimer(interval:NSTimeInterval) {
// if timer already exists, make sure to stop it before starting another one
if _timer != nil {
stopTimer()
}
// reset start date and start new timer
_startDate = NSDate()
_timer = NSTimer.scheduledTimerWithTimeInterval(interval,
target: self,
selector: #selector(timerDidFire),
userInfo: nil, repeats: true)
}
// invalidate & deallocate the timer,
// make sure to call this when you're done with the timer
func stopTimer() {
_timer?.invalidate()
_timer = nil
}
// make sure to stop the timer when the wrapper gets deallocated
deinit {
stopTimer()
}
// called when the timer fires
@objc func timerDidFire() {
// get the change in time, from when the timer first fired to now
let deltaTime = NSDate().timeIntervalSinceDate(_startDate)
// do something with delta time
// invoke the callback method
delegate?.timerDidFire(deltaTime)
}
}
Sie können es dann wie folgt verwenden:
// your view controller class – make sure it conforms to the TimerDelegate
class ViewController: UIViewController, TimerDelegate {
// an instance of the timer wrapper class
let timer = TimerWrapper()
override func viewDidLoad() {
super.viewDidLoad()
// set the timer delegate and start the timer – delegate should be set in viewDidLoad,
// timer can be started whenever you need it to be started.
timer.delegate = self
timer.startTimer(1)
}
func timerDidFire(cumulativeTime: NSTimeInterval) {
// do something with the total time
let dateComponentsFormatter = NSDateComponentsFormatter()
let text = dateComponentsFormatter.stringFromTimeInterval(cumulativeTime)
label.text = text
}
}
Soweit die Angemessenheit der Verwendung einer NSTimer
hier geht, wie Sie nur ein Zeitintervall von 1 Sekunde verwenden, ist eine NSTimer
geeignet. Indem Sie das Zeitintervall über die gesamte Timer-Dauer nehmen, können Sie kleine Brennungenauigkeiten ausgleichen.
Was versuchen Sie eigentlich, wenn der Timer ausgelöst wird? vermutlich nicht nur drucken ... – Wain
Entferne das '()' vom Ende deines 'timerFired' im' # Selector'. Sie sollten jedoch beachten, dass dies immer noch nicht funktioniert, da sich "selbst" in diesem Kontext auf den View-Controller bezieht, nicht auf den Timer. Du musst deine Logik überdenken. – Hamish
Wenn Sie uns sagen können, warum Sie den tatsächlichen Zeitunterschied zwischen den Timer-Aufrufen für die Genauigkeit benötigen, können wir Ihnen möglicherweise helfen, eine Lösung zu finden. Ich vermute, dass Sie hier nicht einmal "NSTimer" verwenden möchten, da sie überhaupt nicht auf Genauigkeit ausgelegt sind. – Hamish