NSOperationQueue not reusing thread on iPhone

cocoa, iphone, multithreading

Solution

NSOperationQueue is designed to pool and re-use threads in the most efficient way possible and in this instance, it seems it decided not re-using threads was the best way to go.

Test code has it's uses (and it is possible you may have identified a corner case where NSOperationQueue does not do the most efficient thing), but that doesn't mean that NSOperationQueue is always horribly inefficient when dealing with real code in real life; in fact my own experience has been to the contrary.

So I'd say use it in your real code and if you have performance issues, dig further into what it's doing with threads behind the scenes. Otherwise don't worry about it.

As an aside, if you are still curious, you might try recording the names of the threads into an array of NSStrings and then printing everything out at the end of the test code, rather than logging as you go along - this will significantly reduce the amount of work done by each NSInvocationOperation.

Problem

I'm using iPhone SDK 3.1.2, and the following code shows the NSOperationQueue does not reuse the thread for each task. The code does not have any problems on Snow Leopard. ``` - (void)applicationDidFinishLaunching:(UIApplication *)application { // Override point for customization after app launch [window addSubview:viewController.view]; [window makeKeyAndVisible]; NSOperationQueue *queue = [[NSOperationQueue alloc] init]; [queue setMaxConcurrentOperationCount:1]; for(int i = 0; i < 100; i++) { NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run) object:nil]; [queue addOperation:op]; [op release]; } } - (void)run { static int tc = 0; if([[NSThread currentThread] isMainThread]) { NSLog(@"MAIN THREAD"); return; } else if([[NSThread currentThread] name] == nil) { [[NSThread currentThread] setName:[NSString stringWithFormat:@"THREAD_%d", tc++]]; } NSLog(@"%@", [[NSThread currentThread] name]); } ``` The output shows it create 100 threads to execute the 100 tasks. ``` 2010-01-07 11:46:03.502 OperationQueueTest[7911:4503] THREAD_0 2010-01-07 11:46:03.506 OperationQueueTest[7911:4d03] THREAD_1 2010-01-07 11:46:03.507 OperationQueueTest[7911:4807] THREAD_2 2010-01-07 11:46:03.510 OperationQueueTest[7911:4d07] THREAD_3 2010-01-07 11:46:03.514 OperationQueueTest[7911:5007] THREAD_4 2010-01-07 11:46:03.516 OperationQueueTest[7911:4f0b] THREAD_5 2010-01-07 11:46:03.518 OperationQueueTest[7911:4e0f] THREAD_6 ... 2010-01-07 11:46:03.740 OperationQueueTest[7911:4ea7] THREAD_97 2010-01-07 11:46:03.744 OperationQueueTest[7911:4dcf] THREAD_98 2010-01-07 11:46:03.746 OperationQueueTest[7911:460f] THREAD_99 ```

Original source