I'm just wondering, is there a better, more efficient function to use than NSTimer? I have a NSTimer code like this on my ViewDidLoad function:
[NSTimer scheduledTimerWithTimeInterval:900.0f target:self selector:@selector(methodToRun) userInfo:nil repeats:YES];
With the function methodToRun:
-(void)methodToRun {
if(currentTime == presetTime) {
//do something
}
}
This works fine but the problem is, this eats up a lot of memory and I am getting memory warnings. So, what's a better, more efficient and less memory consuming way of triggering my methodToRun continuously to check if the currentTime is equal to presetTime?
You can use dispatch_after
.
An alternative solution to this can be achieved by using the dispatch_after method and a weak pointer to self.
__weak id weakSelf = self;
__block void (^timer)(void) = ^{
double delayInSeconds = 1.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
id strongSelf = weakSelf;
if (!strongSelf) {
return;
}
// Schedule the timer again
timer();
// Always use strongSelf when calling a method or accessing an iVar
[strongSelf doSomething];
strongSelf->anIVar = 0;
});
};
// Start the timer for the first time
timer();
With this you will have a scheduled task that will be called at every sec, it will not retain the target (self) and it will end itself if the target is deallocated.
Source:NSTimer alternative
Based on @Anoop's answer here is swift version:
func timerGCD() -> ()
{
weak var weakSelf = self
dispatch_after(
dispatch_time(
DISPATCH_TIME_NOW,
Int64(1.0 * Double(NSEC_PER_SEC))
),
dispatch_get_main_queue())
{
if let strongSelf = weakSelf
{
// Always use strongSelf when calling a method or accessing an iVar
strongSelf.doSomething()
// Schedule the timer again
strongSelf.timerGCD()
}
}
}
And then simply start it with:
timerGCD()
Better swift version using optional chaining and weak self
func timerGCD() -> ()
{
dispatch_after(
dispatch_time(
DISPATCH_TIME_NOW,
Int64(1.0 * Double(NSEC_PER_SEC))
),
dispatch_get_main_queue())
{ [weak self] in
self?.doSomething()
// Schedule the timer again
self?.timerGCD()
}
}
Just run a while loop, and use sleep()
or usleep()
functions at the end of the loop which will define the time interval.
PS: don't do it on main thread
Edit: I see that I am getting downvotes, but can somebody tell me what is wrong with this approach?