Search code examples
objective-cmultithreadingmacosobjective-c-blocksnsthread

Weird behaviour of dispatch_after()


I am writing an application which will do a multiple task simultaneously. One particular task is to do a job once every 200 ms. To achieve this, I am using two methods calling each other. The first method just calls the second and the second method calls the first with a delay using dispatch_after().

After a few iterations(300-400 times) the block in dispatch_after is not executed after 200 ms. It takes ~5-10 seconds before the block is executed. Please let me know the reason for the behaviour(delay). I also tried NSThread (sleepForTimeInterval:) and I am facing the same problem there too.I am stuck. Please help me.

The code is given below.

Screen.h

#import <Foundation/Foundation.h>

@interface Screen : NSObject

-(void) firstMethod;
-(void) secondMethod;
@end

Screen.m

#import "Screen.h"

@implementation Screen

int i=0;
dispatch_queue_t another_queue;
dispatch_time_t pop_time;

-(Screen*) init {
    self = [super init];
    if (self) {
        another_queue = dispatch_queue_create("com.test.timer.2", NULL);
    }
    return self;
}

-(void) firstMethod {
    i++;
    NSLog(@"i value : %d",i);
    [self secondMethod];
}

-(void) secondMethod {
    pop_time = dispatch_time(DISPATCH_TIME_NOW, 200 * NSEC_PER_MSEC);
    dispatch_after(pop_time, another_queue, ^(void){
        [self firstMethod];
    });
}

@end

AppDelegate.h

#import <Cocoa/Cocoa.h>
#import "Screen.h"

@interface AppDelegate : NSObject <NSApplicationDelegate>

@property (assign) IBOutlet NSWindow *window;

@end

AppDelegate.m

#import "AppDelegate.h"

@implementation AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    // Insert code here to initialize your application
    Screen* screen = [[Screen alloc] init];
    dispatch_queue_t first_queue = dispatch_queue_create("com.test.timer", NULL);
    dispatch_block_t blk =^(void) {
        [screen firstMethod];
    };
    dispatch_async(first_queue, blk);
}

@end

Solution

  • Is your app in the foreground when this occurs? If not, you may simply be seeing App Nap kicking in. One of the things it does is throttle timers in background apps.