NSTimer not working - objective-c

I have set up an NSTimer which after one second should perform a instance method called animate
My code looks like this:
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(animate) userInfo:nil repeats:NO];
[timer fire];
This code is put into a touchesBegan method. The method DOES GET CALLED but not after one second it just immediately gets called. Why is this?

You've scheduled a timer and normally that should automatically invoke after 1.0 seconds, but you follow up with a [timer fire] call and that is immediately firing the timer and sending a message to the selector.
Look at the documentation.

Delete [timer fire];
That will solve your problem.

When you call [timer fire] it immediately fires the message to the receiver. You just need to remove that line.

Calling fire causes the message to be sent to its target immediately. See the documentation here.

Related

Any bugs or changes in NSTimer with OC?

I'm testing NSTimer with OC and Swift. When I write with OC, here is something I don't quite understand: is it REQUIRED to add the timer to the NSRunLoop after the timer is inited? If not required, why can't it be invoked in a loop even if I set the repeats to YES?
Here is my code, I just init a timer and set repeats to YES, and what I expect is the code timerTick: should be invoked every 2 seconds, but it doesn't work as I expect... until I add the timer to the NSRunLoop.
OC:
-(void)viewDidLoad {
[super viewDidLoad];
NSTimer *timer = [NSTimer timerWithTimeInterval:2 target:self selector:#selector(timerTick:) userInfo:nil repeats:YES];
}
-(void) timerTick:(NSTimer*) timer{
NSLog(#"ticked,%#",#"aa");
}
I rewrote the same code with Swift
As you can see, I don't add the timer to NSRunLoop, however it works as I expected: the runTimeCode method is invoked every 2 seconds.
var timer:NSTimer!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
timer = NSTimer.scheduledTimerWithTimeInterval(2.0, target: self, selector: "runTimeCode", userInfo: nil, repeats: true)
}
func runTimeCode(){
NSLog("ticked")
}
My Question
Is there any bug in OC with iOS9.2 of NSTimer? I searched a lot with Google, but I didn't find anything saying it is REQUIRED if you want to let the timer works correctly.
How do I use NSTimer?
Is NSTimer usage different between OC and Swift?
First of all, you are using different methods. How come you would get the same result? scheduledTimerWithTimeInterval will automatically add to the NSRunLoop after initializing it. However, timerWithTimeInterval won't. You will need to manually call fire or add it to the NSRunLoop in order to trigger it.
Just like the methods' name mean, scheduledTimerWithTimeInterval will do scheduling for you. As for timerWithTimeInterval, it just gives you a timer. Apple is pretty restricted on the names. Sometimes, you can guess its purpose based on it.
With Objective-C, you should try this method :
NSTimer *timer = [NSTimer scheduleTimerWithTimeInterval:2 target:self userinfo:...];
You can see all method's content in Xcode.

How do I replace this NSTimer with a CADisplayLink?

I realize that a CADisplayLink would be better suited for the nature of my current project, however, i can't quite figure out how to implement a CADisplayLink and replace my NSTimer.
below is the code for my NSTimer
Movement = [NSTimer scheduledTimerWithTimeInterval:0.002 target:self selector:#selector(BarMoving) userInfo:nil repeats:YES];
how can I create a CADisplayLink that will perform the same function but more efficiently?
Create the thing:
_displayLink = [CADisplayLink displayLinkWithTarget:self
selector:#selector(BarMoving)];
Start it running:
[_displayLink addToRunLoop:[NSRunLoop mainRunLoop]
forMode:NSDefaultRunLoopMode];
... that'll cause your display link to issue calls to BarMoving on the main run loop (which is the one associated with the main thread and therefore the main queue) whenever that run loop is in the default mode. So things like when the user has their finger down scrolling a scroll view will pause your timer. NSTimer has the same default behaviour.

NStimer fire first and then on schedule

Is it possible to make a NStimer that fires first when it is initialized and then afterwards on a 0.01 seconds schedule? I have this code..
self.displayTimerTotalTime = [NSTimer timerWithTimeInterval:0.01
target:self
selector:#selector(timerFiredTotalTime:)
userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:self.displayTimerTotalTime forMode:NSRunLoopCommonModes];
Problem is that the user can stop the timer multiple times and run it again, but this creates a 0.01 delay every time that can cause problems for the user experience. It is not good enough to check for the delay later and remove it.
You can call the -fire method to fire the timer at any time. Just add this after the above code:
[self.displayTimerTotalTime fire];
You could always call the selector yourself:
[self timerFiredTotalTime:self.displayTimerTotalTime];

Does NSTimer run across entire app?

If I start an NSTimer like this:
#property (strong) NSTimer * messageTimer;
self.messageTimer = [NSTimer scheduledTimerWithTimeInterval:10.0
target:self
selector:#selector(checkForMessages)
userInfo:nil
repeats:YES];
Does it continue to run when I switch to different view controllers?
Until I cancel it with:
[messageTimer invalidate]; self. messageTimer = nil;
Yes.
Okay, now here is an extended description. NSTimer registers itself on nearest NSRunLoop, that is, current dispatch loop (they may nest). This loop asks various sources for events and calls corresponding callbacks.
When it is time for NSTimer to fire, it returns YES to NSRunLoop and that runs passed callback. There is no such thing as "other current view controller". It is all about first responder and view hierarchy, neither doesn't have any effect on run loops.

NSTimer - NSSlider

I have a NSTimer and a NSSlider in my app. How do I make, that the time interval of the timer would respond instantly to the slider value?
For now it responds just at the beginning. Once the timer is already fired, it doesn't respond any more...
[NSTimer scheduledTimerWithTimeInterval:[slider doubleValue]
target:self
selector:#selector(updateTextFieldWithRandomNumber)
userInfo:nil
repeats:YES];
You cannot change the time interval of a timer once you have created it. You have to invalidate the old timer and create a new one with the new time interval.
What about putting a KVO observation on the slider's doubleValue property and invalidating the timer and recreating it when the notification happens?