I am using NSTimer to run a loop for counting down, then at some point(clicking 'start') I need to run this once again. The first Timer isn't stopped though so countdown pace increases with every run of the function
- (IBAction)startbutton:(id)sender {
timeTick = arc4random_uniform(7)+3;
timeofstart = CACurrentMediaTime();
chosentime = timeTick;
NSLog(#"chosentime værdien er %f", chosentime);
[timer invalidate];
timer = nil;
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(tick) userInfo:nil repeats:YES];
}
- (void) tick {
if (timeTick == 0) {
winnerlabel2.text = #"GO !!!";
}
else {
timeTick --;
NSLog(#"%f", timeTick);
}
}
Here, it is unclear what timer is referring to in these first 2 lines. This 3rd line is creating a new local variable. It looks like you must have an instance variable timer that is created somewhere else. You are invalidating that timer, but then creating a new timer as a local variable that has no permanent handle (because it dies after going out of scope at the end of this method call) and thus every timer after the first never gets invalidated.
[timer invalidate];
timer = nil;
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(tick) userInfo:nil repeats:YES];
Change this 3rd line from...
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(tick) userInfo:nil repeats:YES];
to...
timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(tick) userInfo:nil repeats:YES];
Related
Am I doing something wrong or there is a problem with the system?
Very simple demo: https://github.com/IgorTavcar/UICollectionViewBug.
Here is a collection view and a periodic trigger, started by
- (void)viewDidAppear:(BOOL)animated {
self.timer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:#selector(tick) userInfo:nil repeats:TRUE];
}
Every tick invokes the roladData of collection view.
- (void)tick {
[self.collectionView reloadData];
}
If scroll view
#property(nonatomic) BOOL bounces
is TRUE
then application crashes with EXC_BAD_ACCESS after max. 15 seconds of intensive scrolling /bouncing/.
Any suggestions?
I've also tried to do the
dispatch_async(dispatch_get_main_queue(), ^{
self.timer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:#selector(tick) userInfo:nil repeats:TRUE];
});
and
self.timer = [NSTimer timerWithTimeInterval:0.5 target:self selector:#selector(tick) userInfo:nil repeats:TRUE];
[[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];
...
Fixed:
https://github.com/IgorTavcar/UICollectionViewBug/issues/1
Uncheck "User Interaction Enabled" and "Multiple Touch" from the Collection View Cell in the Story Board.
Use a gesture recognizer to handle it input instead.
Here is my code:
float interval = 0.03;
while (interval > 0.005) {
timer = [NSTimer scheduledTimerWithTimeInterval:interval target:self selector:#selector(onTimer) userInfo:nil repeats:YES];
NSLog(#"%f", interval);
interval = interval - 0.005;
}
How can I make the while loop to wait an specific amount of time after every loop? I've been searching thing like sleep or performSelector:withObject:afterDelay but neither they don't work nor I don't know how to use them... Some help please?
You could use a recursive structure:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Insert code here to initialize your application
[self recursiveMethode:[NSNumber numberWithDouble:0.3]];
}
-(void)onTimer
{
NSLog(#"timer");
}
-(void)recursiveMethode:(NSNumber *)interval
{
timer = [NSTimer scheduledTimerWithTimeInterval:interval.doubleValue target:self selector:#selector(onTimer) userInfo:nil repeats:YES];
NSLog(#"%f", interval.doubleValue);
double delay = 1;
[self performSelector:#selector(recursiveMethode:) withObject:[NSNumber numberWithDouble:interval.doubleValue - 0.05] afterDelay:delay];
}
I have a Foundation CLI tool that uses 5 NSTimers to execute different methods in the background. Ever since implementing these timers (rather than a while loop or similar), I've noticed the CPU usage of the program skyrocket. Does anyone have any information on this?
EDIT:
Here's a code snippet (only 3 timers are currently implemented):
[NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:#selector(executeInterval0Update) userInfo:nil repeats:YES];
[NSTimer scheduledTimerWithTimeInterval:5 target:self selector:#selector(executeInterval1Update) userInfo:nil repeats:YES];
[NSTimer scheduledTimerWithTimeInterval:10 target:self selector:#selector(executeInterval2Update) userInfo:nil repeats:YES];
[runLoop run];
I'm trying to implement retry logic with exponential backoff using NSTimer.
My code looks like this:
-(void)start
{
[NSTimer scheduledTimerWithTimeInterval:0.0 target:self
selector:#selector(startWithTimer:) userInfo:nil repeats:NO];
}
-(void)startWithTimer:(NSTimer *)timer
{
if (!data.ready) {
// timer.timeInterval == 0.0 ALWAYS!
NSTimeInterval newInterval = timer.timeInterval >= 0.1 ? timer.timeInterval * 2 : 0.1;
newInterval = MIN(60.0, newInterval);
NSLog(#"Data provider not ready. Will try again in %f seconds.", newInterval);
NSTimer * startTimer = [NSTimer scheduledTimerWithTimeInterval:newInterval target:self
selector:#selector(startWithTimer:) userInfo:nil repeats:NO];
// startTimer.timeInteval == 0.0 ALWAYS!
return;
}
...
}
The problem I'm having is that the timer NSTimer scheduledTimerWithTimeInterval seems to ignore the interval I'm providing and always sets it to 0.0. Any suggestions on what I'm doing wrong here?
The Apple Documentation has this to say about the timeInterval property on NSTimer.
https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/nstimer_Class/Reference/NSTimer.html
If the receiver is a non-repeating timer, returns 0 (even if a time interval was set).
You will need to use some other means to keep track of what the timer interval should be. I recommend an iVar on your class.
-(void)start
{
_timeInterval = 0.0;
[NSTimer scheduledTimerWithTimeInterval:_timeInterval target:self
selector:#selector(startWithTimer:) userInfo:nil repeats:NO];
}
-(void)startWithTimer:(NSTimer *)timer
{
if (!data.ready) {
_timeInterval = _timeInterval >= 0.1 ? _timeInterval * 2 : 0.1;
_timeInterval = MIN(60.0, _timeInterval);
NSLog(#"Data provider not ready. Will try again in %f seconds.", _timeInterval);
NSTimer * startTimer = [NSTimer scheduledTimerWithTimeInterval:_timeInterval target:self
selector:#selector(startWithTimer:) userInfo:nil repeats:NO];
return;
}
...
}
i need a little help i have a method; countDown which is called when iTunes sends a notification, the method countDown then runs the method timerHit which gets a double minuses one from it then sets the value to a label, the method countDown is set to repeatedly run timerHit, however it doesn't seem to be working.
Here's what i have so far, any help would be much appreciated.
- (void)countDown {
[NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:#selector(timerHit:) userInfo:nil repeats:YES];
}
- (void)timerHit:(NSTimer *)p_timer {
iTunesApplication *iTunes = [SBApplication applicationWithBundleIdentifier:#"com.apple.iTunes"];
if ([iTunes isRunning]) {
double trackDuration = [[iTunes currentTrack] duration];
trackDuration--;
[duration setDoubleValue:trackDuration];
}
}
Thanks, Sami.
If the timer is on a thread then you should run it on a active run loop like so:
NSRunLoop *mLoop = [NSRunLoop currentRunLoop];
[NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:#selector(timerHit:) userInfo:nil repeats:YES];
mRunLoop = YES;
while (mRunLoop && [mLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.01]]);