如何启动一个 NSRunLoop,并确保它有一个被清空的 NSAutoreleasePool?
Posted
技术标签:
【中文标题】如何启动一个 NSRunLoop,并确保它有一个被清空的 NSAutoreleasePool?【英文标题】:How do I start up an NSRunLoop, and ensure that it has an NSAutoreleasePool that gets emptied? 【发布时间】:2010-05-14 09:45:33 【问题描述】:我有一个“同步”任务,它依赖于几个“子任务”,其中包括异步网络操作,但都需要访问单个 NSManagedObjectContext
。由于NSManagedObjectContext
s 的线程要求,我需要这些子任务中的每一个在同一个线程上执行。由于其中一些任务的处理量很大,我需要它们在后台线程上。
目前,我正在我的单例SyncEngine
对象的-init
方法中执行此操作来启动一个新线程:
[self performSelectorInBackground:@selector(initializeSyncThread) withObject:nil];
-initializeSyncThread
方法如下所示:
- (void)initializeSyncThread
self.syncThread = [NSThread currentThread];
self.managedObjectContext = [(MyAppDelegate *)[UIApplication sharedApplication].delegate createManagedObjectContext];
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
[runLoop run];
这是为该线程启动NSRunLoop
的正确方法吗?有更好的方法吗?运行循环只需要处理“performSelector”源,它(及其线程)应该在进程的生命周期内存在。
在设置NSAutoreleasePool
时,我是否应该使用 Run Loop Observers 创建自动释放池并在每次运行后将其排空?
【问题讨论】:
【参考方案1】:我不能 100% 确定这是解决您的问题的最有效方法,但我正在这样做......
由于异步网络操作可能需要不同的时间来完成(或超时),我使用实例变量(在本例中为名为 callComplete
的 BOOL)跟踪它们
当触发网络请求的代码启动时,我的NSURLConnection
消失了,这很神奇,我就这样等待调用完成。
while(!callComplete && [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]])
// Here you can perform other checks, like making sure the method isn't running forever (with a timeout variable)
// Just set callComplete to YES when done
【讨论】:
【参考方案2】:关于NSAutoreleasePool
,我只是在后台运行的选择器的开头创建一个。然后在 Run Loop 完成后(并且我的调用完成)我在返回之前像往常一样释放。
【讨论】:
我有 7-8 个方法(最终可能会有更多)需要在后台线程上自动释放池。如果有办法设置它并将其从运行循环本身中排出(就像 CocoaTouch 如何为主线程做的那样),那肯定会更可取。 我认为您可以使用运行循环观察器来了解它何时处理完事件。有关详细信息,请查看 Apple 文档。以上是关于如何启动一个 NSRunLoop,并确保它有一个被清空的 NSAutoreleasePool?的主要内容,如果未能解决你的问题,请参考以下文章
NSRunLoop 和 NSAutoreleasePool,它们是如何交互的?