如何启动NSRunLoop,并确保它有一个被清空的NSAutoreleasePool?

时间:2010-05-14 09:45:34

标签: iphone cocoa-touch multithreading nsautoreleasepool nsrunloop

我有一个“同步”任务,它依赖于几个“子任务”,包括异步网络操作,但都需要访问单个NSManagedObjectContext。由于NSManagedObjectContext的线程要求,我需要在同一个线程上执行这些子任务中的每一个。由于在某些任务中完成了大量处理,我需要将它们放在后台线程上。

目前,我正在我的单身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创建自动释放池并在每次运行后将其耗尽?

2 个答案:

答案 0 :(得分:0)

我不是百分百肯定这是解决问题的最有效方法,但我这样做......

由于异步网络操作可能需要不同的时间才能完成(或超时),因此我使用实例变量跟踪它们(在本例中为一个名为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
}

答案 1 :(得分:0)

关于NSAutoreleasePool,我只是在后台运行的选择器的开头创建一个。然后在完成运行循环(并且我的调用完成)后,我会像往常一样在返回之前释放。