6

I add timer like this

tim=[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(repeatTim) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:tim forMode:NSDefaultRunLoopMode];

tim it is NSTimer property of my class.

Then i stop it on button click like

[[fbt tim] invalidate];
[fbt setTim:nil];

fbt it is instance of my class.

if i call only invalidate then it doesn't stop, but if i set it to nil then i got EXC_BREAKPOINT

here code of repeatTim method in selector

AppDelegate *appDelegate = [[UIApplication sharedApplication]delegate];
[appDelegate.wbv stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"intal()"]];

I tried to call init and invalidate in

dispatch_async(dispatch_get_main_queue(), ^{})

it also doesn't stop timer.

Sergey92zp
  • 589
  • 4
  • 22
  • 1
    Show the property code. Using ARC? – Wain Sep 11 '13 at 15:25
  • no i don't use ARC. about property @property (nonatomic,retain) MyClass *fbt; – Sergey92zp Sep 11 '13 at 15:40
  • The property for `tim` is the interesting one. Is it `retain`? – Wain Sep 11 '13 at 15:45
  • put 2 breakpoints in your code : one before creating your timer and another one before stopping it. If you hit the first one twice before invalidating `tim` then you will loose a reference to a timer (which will carry on trigger your selector `repeatTim`. – zbMax Sep 11 '13 at 15:47
  • Is [[fbt tim] invalidate] in a different class than the one where you create the timer? Show how you instantiate fbt. Also, try logging fbt to make sure it's not nil. – rdelmar Sep 11 '13 at 16:05

3 Answers3

5

You have more than one timer running . Try this:

-(void)startTimer{
    [self.myTimer invalidate]; // kill old timer
    self.myTimer = [NSTimer scheduledTimerWithTimeInterval:0.2 target:self selector:@selector(doSomething) userInfo:nil repeats:YES];
}

-(void)stopTimer{
    [self.myTimer invalidate];  
    self.myTimer=nil; //set pointer to nil 
}
Tunaki
  • 132,869
  • 46
  • 340
  • 423
Abiola
  • 408
  • 6
  • 6
4

Read documentation for NSTimer:

There are three ways to create a timer:

  1. Use the scheduledTimerWithTimeInterval:invocation:repeats: or scheduledTimerWithTimeInterval:target:selector:userInfo:repeats: class method to create the timer and schedule it on the current run loop in the default mode.

  2. Use the timerWithTimeInterval:invocation:repeats: or timerWithTimeInterval:target:selector:userInfo:repeats: class method to create the timer object without scheduling it on a run loop. (After creating it, you must add the timer to a run loop manually by calling the addTimer:forMode: method of the corresponding NSRunLoop object.)

  3. Allocate the timer and initialize it using the initWithFireDate:interval:target:selector:userInfo:repeats: method. (After creating it, you must add the timer to a run loop manually by calling the addTimer:forMode: method of the corresponding NSRunLoop object.)

You are using method which already adds it to mainLoop from 1. - you need to remove this line or create a timer with 2. approach and leave manual adding.

Also remember that you must send invalidate message from the thread on which the timer was installed. If you send this message from another thread, the input source associated with the timer may not be removed from its run loop, which could prevent the thread from exiting properly.

Community
  • 1
  • 1
Grzegorz Krukowski
  • 18,081
  • 5
  • 50
  • 71
  • i removed line, and call both at dispatch_async(dispatch_get_main_queue(), ^{}) now, but it give me EXC_BREAKPOINT on [fbt setTim:nil]; – Sergey92zp Sep 11 '13 at 15:39
  • What type of exception is that ? Wrong method called , nil exception - try to debug more info. Is "tim" a property in your class - do you retain it or something ? Maybe paste whole class implementation so I can help. – Grzegorz Krukowski Sep 11 '13 at 15:43
  • it was my mistake, i checked all other code and i found that my method was called from a cycle. thanks to all. – Sergey92zp Sep 11 '13 at 16:49
0

I have tried every possible solution found but not able to resolve that at the end I have set repeat "false" while initialising timer like below

self.timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(viewcontroller.methodname), userInfo: nil, repeats: false)

And need to add above line in my selector method for whatever the condition for which I wanted to repeat the time.

For example:- My requirement is I want to repeatedly call some method until one condition satisfied. So instead of adding repeats true I set it false as repeat true does not invalidate timer in my case.

I have added below in my viewdidload method

self.timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(viewcontroller.method), userInfo: nil, repeats: false)

in selector function I added below code:-

func method{
   if condition matched{
        // here your timer will be invalidated automatically
   }
   else{
       self.timer = Timer.scheduledTimer(timeInterval: 1, target: self,selector: #selector(viewcontroller.method), userInfo: nil,repeats: false)
   }
}

Hope this will solve your problem.

Happy Coding :)

Priyanka
  • 159
  • 2