Run Repeating Nstimer with Gcd

Run repeating NSTimer with GCD?

NSTimers are scheduled on the current thread's run loop. However, GCD dispatch threads don't have run loops, so scheduling timers in a GCD block isn't going to do anything.

There's three reasonable alternatives:

  1. Figure out what run loop you want to schedule the timer on, and explicitly do so. Use +[NSTimer timerWithTimeInterval:target:selector:userInfo:repeats:] to create the timer and then -[NSRunLoop addTimer:forMode:] to actually schedule it on the run loop you want to use. This requires having a handle on the run loop in question, but you may just use +[NSRunLoop mainRunLoop] if you want to do it on the main thread.
  2. Switch over to using a timer-based dispatch source. This implements a timer in a GCD-aware mechanism, that will run a block at the interval you want on the queue of your choice.
  3. Explicitly dispatch_async() back to the main queue before creating the timer. This is equivalent to option #1 using the main run loop (since it will also create the timer on the main thread).

Of course, the real question here is, why are you creating a timer from a GCD queue to begin with?

Timer with Grand Central Dispatch

Don't do what you're trying to do. Just run the timer on the main thread. The timer also needs to be scheduled on a runloop (so use scheduledTimerWithTimeInterval:target:selector:userInfo:repeats: to create it).

Now, if you need to, use dispatch_async in the method called by the time (timerFunction) to perform your processing on a background thread.

Swift - Timer with GCD with condition

Try this:

var timer: Timer?

// every time you set new percent start new Timer. if in 15 sec it will not reach new percent -> cancellation begins
func startNewTimer() {
timer?.invalidate()
timer = Timer.scheduledTimer(withTimeInterval: 15, repeats: false, block: { (_) in
// do cancellation
})
}

Difference in scheduling NSTimer in main thread and background thread?

NSTimer requires an active run loop, when initialized in Main Thread it automatically uses the main run loop. If you need to make a background timer you need attach it to the thread’s run loop and invoke run() to make it active.

  1. NSTimer needs one live NSRunLoop to execute it’s events. In main thread, the NSRunLoop is always live and will never stop until the app is terminated, but in other threads, you must invoke run() to active the NSRunLoop.

  2. NSTimer must invoke invalidate() to release the current timer, otherwise, the timer will retain a strong reference of the current instance of target, and it will remain in memory until invalidate() invoked or app terminated;

  3. NSTimer must created and invalidated in the same thread, and a lot of times, we may forget that.

Take a look at this example , it may be helpful >> http://www.acttos.org/2016/08/NSTimer-and-GCD-Timer-in-iOS/
and the documentation : https://developer.apple.com/documentation/foundation/nstimer

dispatch_after looped / repeated

The dispatch_after(...) call returns immediately no matter when it is scheduled to run. This means that your loop is not waiting two seconds between dispatching them. Instead you are building an infinite queue of things that will happen two seconds from now, not two seconds between each other.

So yes, you are stuck in an infinite loop of adding more and more blocks to be executed. If you want something to happen every two second then you could use a repeating NSTimer or have the block dispatch_after inside itself (so that the second block runs two seconds after the first).



Related Topics



Leave a reply



Submit