How to manage the NSRunLoop autostart pool running in a secondary thread?

In the Apple MVCNetworking sample class, the NetworkManager class includes this method to maintain a run loop in a secondary thread dedicated to network activity (to start NSURLConnection asynchronously):

 - (void)networkRunLoopThreadEntry { while(YES) { NSAutoreleasePool *pool; pool = [[NSAutorelease alloc] init]; [[NSRunLoop currentRunLoop] run]; [pool drain]; } } 

Since the run method exits immediately if there is no source connected to the start loop, it looks like an endless while that consumes CPU resources uselessly if NSURLConnection is not currently connected to the start loop.

On the other hand, in order to support a startup loop, some suggests scheduling an empty port in a run loop:

  - (void)networkRunLoopThreadEntry { NSAutoreleasePool *pool = [[NSAutorelease alloc] init]; NSPort *port = [NSPort port]; [[NSRunLoop currentRunLoop] addPort:port forMode:NSRunLoopCommonModes]; [NSRunLoop run]; [pool drain]; } 

However, in this case, I am worried that the run method will never exit, which means that the pool will never be exhausted, which means that all objects allocated and auto-implemented in the secondary stream will flow.

What will be the way?

(In the context, like many others, I am trying to encapsulate an asynchronous NSURLConnection inside a NSOperation , which means that it can be run outside the main thread. Also, the MVCNetworking code sample since WWDC 2010 Network Apps for iPhone OS sessions seem to suggest which is nice to have a unique secondary stream dedicated to network transmissions to prevent the latency of the main stream.)

+4
source share
1 answer

You can create a CFRunLoopObserver for the kCFRunLoopBeforeWaiting action and add it to the run loop. In the observer leader, release the old pool and create a new one. A missed example:

 static void resetPoolCallout(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info) { NSAutoreleasePool **poolPointer = (NSAutoreleasePool **)info; [*poolPointer release]; *poolPointer = [[NSAutoreleasePool alloc] init]; } - (void)networkRunLoopThreadEntry { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSPort *port = [NSPort port]; [[NSRunLoop currentRunLoop] addPort:port forMode:NSRunLoopCommonModes]; CFRunLoopObserverContext observerContext = { .version = 0, .info = (void*)&pool, .retain = NULL, .release = NULL, .copyDescription = NULL }; CFRunLoopObserverRef observer = CFRunLoopObserverCreate(NULL, kCFRunLoopBeforeWaiting, true, 0, resetPoolCallout, &observerContext); CFRunLoopAddObserver(CFRunLoopGetCurrent(), observer, kCFRunLoopCommonModes); [[NSRunLoop currentRunLoop] run]; CFRunLoopRemoveObserver(CFRunLoopGetCurrent(), observer, kCFRunLoopCommonModes); CFRelease(observer); [pool release]; } 
+6
source

All Articles