How to wait for a thread to finish in Objective-C How to wait for a thread to finish in Objective-C multithreading multithreading

How to wait for a thread to finish in Objective-C


Here's another way to do it using GCD:

- (void)main{    [self doStuffInOperations];}- (void)doStuffInGCD{    dispatch_group_t d_group = dispatch_group_create();    dispatch_queue_t bg_queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);    dispatch_group_async(d_group, bg_queue, ^{        [self doSomething:@"a"];    });    dispatch_group_async(d_group, bg_queue, ^{        [self doSomething:@"b"];    });    dispatch_group_async(d_group, bg_queue, ^{        [self doSomething:@"c"];    });    // you can do this to synchronously wait on the current thread:    dispatch_group_wait(d_group, DISPATCH_TIME_FOREVER);    dispatch_release(d_group);    NSLog(@"All background tasks are done!!");    // ****  OR  ****    // this if you just want something to happen after those are all done:    dispatch_group_notify(d_group, dispatch_get_main_queue(), ^{        dispatch_release(d_group);        NSLog(@"All background tasks are done!!");            });}- (void)doSomething:(id)arg{    // do whatever you want with the arg here }


Use an NSOperationQueue, like this
(from memory so forgive any minor errors -- you'll get the basic idea):

// ivarsNSOperationQueue *opQueue = [[NSOperationQueue alloc] init];// count can be anything you like[opQueue setMaxConcurrentOperationCount:5];- (void)main{    [self doStuffInOperations];}// method- (void)doStuffInOperations{    // do parallel task A    [opQueue addOperation:[[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(doSomething:) object:@"a"] autorelease]];    // do parallel task B    [opQueue addOperation:[[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(doSomething:) object:@"b"] autorelease]];    // do parallel task C    [opQueue addOperation:[[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(doSomething:) object:@"c"] autorelease]];    [opQueue waitUntilAllOperationsHaveFinished];    // now, do stuff that requires A, B, and C to be finished, and they should be finished much faster because they are in parallel.}- (void)doSomething:(id)arg{    // do whatever you want with the arg here     // (which is in the background,     // because all NSOperations added to NSOperationQueues are.)}


My first inclination is to not do what you are suggesting. The technique I've used before is to give the thread a selector to a method in the originating object (which is on the main thread). When the second thread is started, the main thread keeps executing, but puts up a busy indicator of some sort on the display. This allows user interaction to continue if required.

When the second thread ends, just before it shuts down, it calls the selector on the main thread. The method that the selector references then removes the busy indicator from the display and tells the main thread to update, picking up whatever data the second thread has generated.

I've used this successfully for an app which accesses a web service (on the second thread) and then updates the display once data is returned without locking it. This makes the user experience much nicer.