本文介绍了如何在主 gui 线程之外工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have an object that when you instantiate it and send it a message it takes a long time to run. It is designed to call back a delegate object with the results of the job. There are multiple calls back to the delegate over time.

我知道我需要把工作放在一个线程中.我知道如何制作线程.我知道如果一个线程想要发送消息,它需要调用 performSelectorOnMainThread.但这就是我目前所能做的.

I know I need to put the job in a thread. I know how to make a thread. I know that if a thread wants to send a message it needs to call performSelectorOnMainThread. But thats as much as I can work out so far.

是否有关于如何将所有这些组合在一起的教程?目前我真的只是猜测.

Are there any tutorials on how to actually put all this together? At the moment im really just guessing.

推荐答案

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

I would suggest using a NSOperationQueue with a NSInvocationOperation. The NSOperationQueue will automatically scale to use as many threads as is optimal under current load, and is intended for executing long running tasks. There is nothing that stops you from calling back to your delegate several times from an operation running on a operation queue.

像这样设置你的队列:

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

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

I assume that you want no extra arguments sent to your task but the delegate to report back to. In this scenario using a plain NSInvocationOperation is easiest. I also assume that the method that implements the task, and the method that receives the callback are in the same class. Start a task like so:

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

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

And then implement executeTask:. Call back to the delegate on the main thread, so that the UI can safely be updated in the callback. You could wait for the callback to complete if you like, but I skip this, all callbacks will be queued on the main thread.

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

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

I have also thrown in a local autorelease pool. This can be necessary when doing lengthy work in background tasks without a run-loop in place. Good practice.

这篇关于如何在主 gui 线程之外工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-29 02:08
查看更多