2012-07-11 46 views
4

在蘋果公司的MVCNetworking示例代碼,所述NetworkManager類包括(爲了運行NSURLConnection異步地)這種方法以保持在輔助線程一個運行循環專用於網絡活動:如何管理在輔助線程中運行的NSRunLoop的autorelease池?

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

由於run方法立即如果退出沒有源代碼連接到運行循環,這看起來像一個無限循環,如果當前沒有NSURLConnection連接到運行循環,它將無用地佔用CPU資源。

在另一方面,以保持運行循環活躍,somesuggests安排在運行循環的空口:

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

然而,在這種情況下,我的擔心是,run方法永遠不會退出,這意味着池永遠不會被排空,這意味着在次要線程中分配和自動釋放的所有對象都將泄漏。

那麼要走的路是什麼?我想在NSOperation內部封裝一個異步NSURLConnection,這意味着它可以在主線程之外被觸發。另外,MVCNetworking示例代碼以及WWDC 2010屆網絡應用程序的iPhone OS,似乎表明它是有專門用於網絡傳輸一個獨特的輔助線程,以防止在主線程等待一個好主意。)

回答

6

可以爲kCFRunLoopBeforeWaiting活動創建CFRunLoopObserver並將其添加到運行循環中。在觀察者的標註中,釋放舊池並創建一個新池。未經測試的示例:

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]; 
} 
+0

您如何在ARC中執行此操作? – user102008 2014-02-04 07:53:17

相關問題