如何在主gui线程之外做工作?

时间:2009-09-16 12:27:55

标签: objective-c multithreading

我有一个对象,当你实例化它并向它发送一条消息时,它需要很长时间才能运行。它旨在使用作业结果回调delegate对象。随着时间的推移,有多个回拨到delegate

我知道我需要把工作放在一个线程中。我知道如何制作一个帖子。我知道如果线程想要发送消息,则需要调用performSelectorOnMainThread。但到目前为止,我可以解决这个问题。

有没有关于如何将所有这些放在一起的教程?目前我真的只是猜测。

3 个答案:

答案 0 :(得分:4)

我建议使用NSOperationQueueNSInvocationOperationNSOperationQueue将自动扩展以使用当前负载下最佳的线程数,并用于执行长时间运行的任务。没有什么可以阻止您从操作队列上运行的操作多次回调您的委托。

像这样设置你的队列:

NSOperationQueue* queue = [[NSOperationQueue alloc] init];

我假设您不希望向您的任务发送额外的参数,而是要向代表报告。在这种情况下,使用普通NSInvocationOperation是最简单的。我还假设实现任务的方法和接收回调的方法属于同一个类。像这样开始一个任务:

NSInvocationOperation* operation;
operation = [[NSInvocationOperation alloc] initWithTarget:self
                                                 selector:@selector(executeTask:)
                                                   object:self];
[queue addOperation:operation];
[operation release];

然后实施executeTask:。回调主线程上的委托,以便可以在回调中安全地更新UI。如果你愿意,你可以等待回调完成,但是我跳过这个,所有的回调都会在主线程上排队。

-(void)executeTask:(id)delegate;
{
  while (notDone) {
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    [delegate performSelectorOnMainThread:@selector(taskWillProgress:)
                               withObject:self
                            waitUntilDone:NO];
    // Do stuff
    [pool release];
  };
}

我还投入了一个本地自动释放池。在没有运行循环的后台任务中进行冗长的工作时,这可能是必要的。好的做法。

答案 1 :(得分:2)

一个很好的介绍是Apple的Concurrency Programming Guide

如果您需要有关线程的特定信息,还可以查看Threading Programming Guide

在这些读数之后,NSOperationNSThread,Grand Central Dispatch,openCL以及如何在Mac OS X上设计并发应用程序对您来说毫无秘密。

答案 2 :(得分:1)

最简单的方法是将NSOperationNSOperationQueue结合使用。

看看Apple的Concurrency Programming Guide