How to check if a NSTimer is running or not in Swift?
What I do (in both languages) is to make my timer weak. In swift it would be a weak optional.
weak var myTimer: NSTimer?
Then I create a timer with
myTimer = NSTimer.scheduledTimerWithTimeInterval(1,
target: self,
selector: "timerFired:",
userInfo: nil,
repeats: false)
And then you can use
if timer == nil
to tell if it's running.
To stop the timer you just call
myTimer?.invalidate()
In Objective-C it would be
[myTimer invalidate];
That works in Objective-C because sending messages to nil pointers is valid, and just does nothing.
If you don't want to use a weak optional, you can query a timer to see if it's running by looking at it's valid
property.
Check if Timer is running
I recommend to use self-checking startTimer()
and stopTimer()
functions, the timer will be started only if it's not currently running, the stop function sets the timer
variable reliably to nil
.
var timer : Timer?
func startTimer()
{
if timer == nil {
timer = Timer.scheduledTimer...
}
}
func stopTimer()
{
if timer != nil {
timer!.invalidate()
timer = nil
}
}
Swift how to check if timer is done using time from certain variable?
There's an easier way to do this, using a single timer which you use to update a display, and just keep track of whether you are running or walking - something like this
@IBAction func cmdStartStopAction(_ sender: Any)
{
durationTimerDisplay = 0.1 // this will update the display every 0.1 seconds
currentlyRunning = true // assume we start by running
if timerDisplay == nil // this means we are starting the timer
{
durationRun = Double(txtTimerRun.text!)! // assumes you have a text box to enter the times
durationWalk = Double(txtTimerWalk.text!)!
durationRemaining = durationRun // we can use this to display a countdown timer
// start the display update timer
timerDisplay = Timer.scheduledTimer(timeInterval: durationTimerDisplay, target: self, selector: #selector(onTimerDisplay), userInfo: nil, repeats: true)
}
else
{
timerDisplay.invalidate()
timerDisplay = nil
}
}
@objc func onTimerDisplay()
{
durationRemaining -= durationTimerDisplay // count down timer
if durationRemaining <= 0 // switch between running and walking when you reach zero
{
// switch from running to walking, or walking to running
currentlyRunning = !currentlyRunning
if currentlyRunning {
durationRemaining = durationRun
}
else {
durationRemaining = durationWalk
}
}
// create a display using a label lblTimer
if currentlyRunning {
lblTimer.text = String(format: "RUN: %.1f", durationRemaining)
}
else {
lblTimer.text = String(format: "WALK: %.1f", durationRemaining)
}
}
How to find if NSTimer is active or not?
When a non repeating timer fires it marks itself as invalid so you can check whether it is still valid before cancelling it (and of course then ridding yourself of it).
if ( [timer isValid] && yourOtherCondition){
[timer invalidate], timer=nil;
}
In your case you have a repeating timer so it will always be valid until you take some action to invalidate it. Looks like in this case you are running a countdown so it will be up to you to make sure you invalidate and rid yourself of it when the countdown reaches the desired value (In your updateCountdown method)
swift 3 check if timer running
This is expected. You are assigning the new Timer instance to weak var
inside your function, which will cause it to be deallocated when you exit function scope. The function's timer
variable must be declared as inout
func startTimer(timer: inout Timer?, interval: Double, _selector: Selector, _repeats: Bool) {
if (timer == nil){
timer = Timer.scheduledTimer(timeInterval: interval, target: self, selector: _selector, userInfo: nil, repeats: _repeats)
}
The same goes for your second function - you are assigning nil
only to local variable inside function scope, not to the variable outside.
iOS - check if Timer is valid or not
In your code, instead of using timer.isValid
, how about change to timer != nil
, like following,
if result != nil {
timer.invalidate()
// timer = Timer.scheduledTimer(timeInterval:2, target: self, selector: #selector(ViewController.noResults), userInfo: nil, repeats:false)
}
if timer != nil { // here
print("has not been 2 seconds yet")
} else {
print("do some action")
}
Hope this help!
How to check if NSTimer has been already invalidated
Once you invalidate the timer, simply call release
on it (assuming you've retained the reference you're holding on to) and then nil out your reference. That way when you exit the view, trying to invalidate the timer a second time will just call that method on nil instead, which does nothing.
Alternatively, you can use -[NSTimer isValid]
to check if it's valid before invalidating, but there's really no reason to hold onto your reference after invalidating it the first time anyway. Also, if your real problem is that you haven't retained your reference and so the first -invalidate
actually leaves you with a reference pointing at a released object, then calling -isValid
won't help anyway.
Related Topics
Swift Select All Photos from Specific Photos Album
How to Hide API Keys in Github for iOS (Swift) Projects
Why am I Getting Com.Facebook.Sdk.Login Error 308
Swift Core Data Sync with Web Server
Reload View When @Published Is Changed
Create Navbar Programmatically with Button and Title Swift
How to Center a Label Horizontally for All iOS Devices in Swift
How to Add a Ibaction to a Button Programmatically in Swift 4
How to Check If Device Orientation Is Landscape Left or Right in Swift
Swift: Load Custom Uiview from Xib Programmatically
iOS Swift Nsmutabledata Has No Member Appendstring
Using Static Libraries with Cocoapods 1.5 No Such Module at Import
Automatically Change Cell Height Based on Content - Swift