在iOS上如何从后台线程发送消息到主线程

6

我有一个iOS应用程序,我正在后台线程上完成任务。每当完成一个任务时,我希望向主线程发送一条消息,以便我可以将自定义进度条移动到适当的阶段。

最简单但最安全的方法是什么?

编辑1

这是我正在使用的方法:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 
                                         (unsigned long)NULL), ^(void) {

     // get background tasks done. 
     [self.background backgroundMethod];

});

编辑2

这是我尝试使用@Madboy的答案时的示例。在执行后台方法的类中,我有一个指向进度条的指针。我们认为这会起作用吗?(请注意,还更改了编辑1)。

@implementation BackgroundClass
@synthesize delegate;
@synthesize customProgressBar

- (void)backgroundMethod
{
    // Run tasks
}

- (void)delegateSaysBackgroundMethodIsFinished
{
    [self performSelectorOnMainThread:@selector(tasksDone:) withObject:self.customProgressBar waitUntilDone:NO];

}

@implementation CustomProgressBar

- (void)tasksDone
{
    // change UI to reflect progress done. 
}

由于您正在使用dispatch_async(),请查看我的答案,该答案也使用了dispatch_async(),因为这将是首选方法。 - Michael Ochs
3个回答

10

这取决于你正在做什么。你是在使用GCD在后台执行任务吗?那么你只需要调用:

dispatch_async(dispatch_get_main_queue(), ^{
    //your main thread task here
});

如果你在一个NSThread中运行,可以这样做:

[myObject performSelectorOnMainThread:YOURSELECTOR withObject:YOUROBJECT waitUntilDone:NO];

这个程序会在主线程的哪里运行?它会在调用原始后台线程的类和方法内部吗? - Eric Brotto
1
这将在当前运行循环的末尾或下一个运行循环的开始执行,取决于您何时调用这些方法。您从另一个线程中执行的所有操作都无法在原始方法本身中执行,因为该方法已经结束并且不再在堆栈上了!>> 请注意我上面的更改,我选择了错误的NSThread方法,因为我不使用它... - Michael Ochs
谢谢您的努力。如果您有时间,能否看一下我的EDIT 2,并让我知道您的想法? - Eric Brotto

4
你可以使用NSObjectperformSelectorOnMainThread:withObject:waitUntilDone:方法。
waitUntilDone参数是一个布尔值。你可以传递YES,使你的后台线程等待直到主线程上的方法完成。你可以传递NO,只需在后台线程上同时执行该方法并与主线程继续执行。

0

NSNotificationCenter 允许线程之间进行消息传递。您可以设置一个“监听器”,然后广播通知 - 苹果的文档非常好,很容易上手。


3
请注意,通知将在创建它们的线程中被分发!因此,您仍然需要自己更改线程! - Michael Ochs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接