iPhone: Using dispatch_after to mimick NSTimer
        Posted  
        
            by 
                Joseph Tura
            
        on Stack Overflow
        
        See other posts from Stack Overflow
        
            or by Joseph Tura
        
        
        
        Published on 2011-01-17T15:46:14Z
        Indexed on 
            2011/01/17
            16:53 UTC
        
        
        Read the original article
        Hit count: 336
        
Don't know a whole lot about blocks. How would you go about mimicking a repeating NSTimer with dispatch_after? My problem is that I want to "pause" a timer when the app moves to the background, but subclassing NSTimer does not seem to work.
I tried something which seems to work. I cannot judge its performance implications or whether it could be greatly optimized. Any input is welcome.
#import "TimerWithPause.h"
@implementation TimerWithPause
@synthesize timeInterval;
@synthesize userInfo;
@synthesize invalid;
@synthesize invocation;
+ (TimerWithPause *)scheduledTimerWithTimeInterval:(NSTimeInterval)aTimeInterval target:(id)aTarget selector:(SEL)aSelector userInfo:(id)aUserInfo repeats:(BOOL)aTimerRepeats {
    TimerWithPause *timer = [[[TimerWithPause alloc] init] autorelease];
    timer.timeInterval  = aTimeInterval;
    NSMethodSignature *signature = [[aTarget class] instanceMethodSignatureForSelector:aSelector];
    NSInvocation *aInvocation = [NSInvocation invocationWithMethodSignature:signature];
    [aInvocation setSelector:aSelector];
    [aInvocation setTarget:aTarget];
    [aInvocation setArgument:&timer atIndex:2];
    timer.invocation = aInvocation;
    timer.userInfo      = aUserInfo;
    if (!aTimerRepeats) {
        timer.invalid = YES;
    }
    [timer fireAfterDelay];
    return timer;
}
- (void)fireAfterDelay {
    dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, self.timeInterval * NSEC_PER_SEC);
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_after(delay, queue, ^{
    [invocation performSelectorOnMainThread:@selector(invoke) withObject:nil waitUntilDone:NO];
    if (!invalid) {         
        [self fireAfterDelay];
    }
});
}
- (void)invalidate {
    invalid = YES;
    [invocation release];
    invocation = nil;
    [userInfo release];
    userInfo = nil;
}
- (void)dealloc {
    [self invalidate];
    [super dealloc];
}
@end
        © Stack Overflow or respective owner