在Apple的MVCNetworking示例代码中,NetworkManager
类包含此方法,以在专用于网络活动的辅助线程中维护运行循环(以便异步运行NSURLConnection
):< / p>
- (void)networkRunLoopThreadEntry
{
while(YES) {
NSAutoreleasePool *pool;
pool = [[NSAutorelease alloc] init];
[[NSRunLoop currentRunLoop] run];
[pool drain];
}
}
由于如果没有源连接到运行循环,run
方法会立即退出,这看起来像一个无限while
循环,如果当前没有连接NSURLConnection,它将无用地消耗CPU资源运行循环。
另一方面,为了保持运行循环的活动,some suggests在运行循环中安排一个空端口:
- (void)networkRunLoopThreadEntry
{
NSAutoreleasePool *pool = [[NSAutorelease alloc] init];
NSPort *port = [NSPort port];
[[NSRunLoop currentRunLoop] addPort:port forMode:NSRunLoopCommonModes];
[NSRunLoop run];
[pool drain];
}
但是,在这种情况下,我担心run
方法永远不会退出,这意味着池永远不会被耗尽,这意味着在辅助线程中分配和自动释放的所有对象都将泄漏。
那是什么方式?
(对于上下文,与其他许多人一样,我正在尝试将异步NSURLConnection
封装在NSOperation
内,这意味着它可以在主线程之外触发。此外,MVCNetworking示例代码,以及WWDC 2010会议 iPhone OS网络应用程序,似乎建议有一个专用于网络传输的独特辅助线程,以防止主线程上的延迟。)< / p>
答案 0 :(得分: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];
}