Devarshi
Devarshi

Reputation: 16758

NSOperationQueue and Dispatch Queue as replacement of NSThread performing a repetitive task

I have an application in which I am repetitively calling a method in background. I implemented this by following below steps:

  1. created a background thread,
  2. called the appropriate method on the created thread,
  3. called sleep method on the thread, and
  4. again called the previously invoked method.

Below is the code which I used:

- (void) applicationDidFinishLaunching:(NSNotification *)notification
    [NSApplication detachDrawingThread:@selector(refreshUserIdPassword) toTarget:self withObject:nil];
}

-(void)refreshUserIdPassword
{
    [self getAllUserIdsPasswordsContinousely];
    [NSThread sleepForTimeInterval:180];
    [self refreshUserIdPassword];

}

I have read that NSThread is not the best way to perform background task, and there are other classes provided in cocoa, such as - NSOperationQueue and GCD, which should be preferred over NSThread to perform an asynchronous task. So I am trying to implement the above specified functionality using the alternative classes.

Problem is - though I am able to perform an asynchronous task using these classes, I am unable to perform a repetitive task (as in my case) using these classes.

Can someone throw some light on this and guide me towards the correct direction?

Upvotes: 2

Views: 1104

Answers (3)

Andrew Madsen
Andrew Madsen

Reputation: 21383

I think you'll get a stack overflow (no pun intended) using the code you've posted. -refreshUserIdPassword recurses infinitely...

How about using GCD?

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    // Insert code here to initialize your application
    dispatch_source_t timerSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));
    dispatch_source_set_timer(timerSource, dispatch_time(DISPATCH_TIME_NOW, 0), 180*NSEC_PER_SEC, 10*NSEC_PER_SEC);
    dispatch_source_set_event_handler(timerSource, ^{
        [self getAllUserIdsPasswordsContinuously];
    });
    dispatch_resume(timerSource);
    self.timer = timerSource;
}

Upvotes: 5

Thomas Zoechling
Thomas Zoechling

Reputation: 34253

As the question also has a grand-central-dispatch tag:
If you need to run something in the background based on a regular interval, you could also use a dispatch_source timer.
Apple provides a very extensive example in the Concurrency Programing Guide.

If you don't need a background thread, you could use NSTimer (as paulbailey mentioned) or even more simple: NSObject's performSelector:withObject:afterDelay:

Upvotes: 1

paulbailey
paulbailey

Reputation: 5346

You're looking in the wrong place. As you say, NSOperationQueue isn't suited for this type of task. NSTimer is Cocoa's solution to this problem.

Upvotes: 3

Related Questions