在我的应用程序中,我在发送HTTP请求之前让进度指示器开始动画。 完成处理程序在块中定义。收到响应数据后,我从块内隐藏进度指示器。我的问题是,正如我所知,UI更新必须在主线程中执行。我怎么能确定它?
如果我在窗口控制器中定义一个更新UI的方法,让块调用方法而不是直接更新UI,那么它是一个解决方案吗?
答案 0 :(得分:10)
此外,如果您的应用定位到iOS> = 4,则可以使用Grand Central Dispatch:
dispatch_async(dispatch_get_main_queue(), ^{
// This block will be executed asynchronously on the main thread.
});
当使用performSelect…
方法所采用的单选择器和对象参数无法轻松表达自定义逻辑时,这非常有用。
要同步执行一个块,请使用dispatch_sync()
- 但请确保您当前没有在主队列上执行,否则GCD将会死锁。
__block NSInteger alertResult; // The __block modifier makes alertResult writable
// from a referencing block.
void (^ getResponse)() = ^{
NSAlert *alert = …;
alertResult = [NSAlert runModal];
};
if ([NSThread isMainThread]) {
// We're currently executing on the main thread.
// We can execute the block directly.
getResponse();
} else {
dispatch_sync(dispatch_get_main_queue(), getResponse);
}
// Check the user response.
if (alertResult == …) {
…
}
答案 1 :(得分:0)
你可能误解了一些东西。使用块并不意味着您的代码在后台线程中运行。有许多插件异步工作(在另一个线程中)并使用块。
有几种方法可以解决您的问题。
您可以使用[NSThread isMainThread]
检查您的代码是否在主线程中运行。这有助于您确保自己不在后台。
您还可以使用performSelectorInMainThread:SEL
或performSelectorInBackground:SEL
在主要或后台执行操作。
当您尝试从bakcground线程调用UI时,应用程序会立即崩溃,因此很容易找到错误。