NSThread和UIViewController交互

Air*_*Ltd 5 iphone cocoa multithreading

如果我生成一个新线程,然后在其中我将一个新控制器推到我的UINavigationController上,使用这样的代码......

(a)不工作

-(void)myCallbackInThread
{
    // move on...
    UIApplication* app = [UIApplication sharedApplication];
    [app changeView];
}
Run Code Online (Sandbox Code Playgroud)

然后我发现视图出现,但不响应用户输入.

如果我改变这样的代码

(b)工作

-(void)myCallbackInThread
{
    // move on...
    UIApplication* app = [UIApplication sharedApplication];
    [app performSelectorOnMainThread:@selector(moveToMain) withObject:nil waitUntilDone:FALSE];
}
Run Code Online (Sandbox Code Playgroud)

一切都运转正常.

任何暗示为什么?

Jas*_*oco 2

在您的情况下,这实际上取决于 [app changeView] 中发生的情况,但它停止响应的原因很可能是您的新辅助线程上没有运行循环调度事件(更多内容见下文)。然而,一般来说,从辅助线程更新 GUI 是一个非常糟糕的主意。正如您已经发现的,所有这些事件都应该通过主线程。

您的第二个示例工作而不是第一个示例工作的主要原因是 UIApplication 在主线程上为您设置并处理运行循环和事件调度程序。因此,当您调用performSelectorInMainThread时,选择器将被分派到主运行循环,该循环随后能够处理您的gui输入和其他事件。事件调度程序也由 UIApplication 在主线程上运行和管理。

所以基本上,不要在辅助线程上执行任何 GUI 管理活动。将它们分派到主线程。如果您需要在辅助线程上进行处理(例如计时器或异步调用等),那么您必须在该线程上启动并管理您自己的运行循环(有关管理运行循环的更多信息,请参阅NSRunLoop )。