2

我正在尝试在加载视图时从 Internet 获取数据。为了不滞后 UI,我正在执行 HTML 下载和解析,方法是使用

[self performSelectorInBackground:@selector(alertThreadMethod) withObject:nil];

它检查是否有在线警报。然而,为了在视图上显示信息,iOS 说我需要使用主线程。所以我在之后立即调用显示代码:

[self performSelectorInBackground:@selector(alertThreadMethod) withObject:nil];
[self loadAlert];

在这样做时,[self loadAlert];实际上在后台的选择器之前运行(它更快)。因此,它没有后台选择器应该提供的信息。

我怎样才能确保[self loadAlert];运行后?还是有更好的方法来做到这一点?

4

2 回答 2

5

您可以将 loadAlert 调用移动到 alertThreadMethod 或使用Grand Central Dispatch串行队列,例如,

dispatch_queue_t queue = dispatch_queue_create("com.example.MyQueue", NULL);
dispatch_async(queue, ^{
    [self alertThreadMethod];
    [self loadAlert];
});
dispatch_release(queue);

或者,如果 loadAlert 正在更新 UI,因为您在主队列中进行 UI 更新,您将执行以下操作:

dispatch_queue_t queue = dispatch_queue_create("com.example.MyQueue", NULL);
dispatch_async(queue, ^{
    [self alertThreadMethod];
    dispatch_async(dispatch_get_main_queue(), ^{
        [self loadAlert];
    });
});
dispatch_release(queue);

顺便说一句,如果您只是在后台执行这项任务,而不是创建自己的串行队列,您可能只使用现有的后台队列之一。如果您需要串行性质,您只需要创建一个队列(即您将有大量的 dispatch_async 调用并且您不能让它们同时运行)。但在这个简单的例子中,这可能会更高效一些,绕过串行队列的创建和释放:

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
    [self alertThreadMethod];
    dispatch_async(dispatch_get_main_queue(), ^{
        [self loadAlert];
    });
});
于 2012-06-21T22:02:53.017 回答
1

在您的 alertThreadMethod 中,获得信息后,调用方法 performSelectorOnMainThread:withObject:waitUntilDone: 并将选择器传递给您的 loadAlert 方法。

-(void)alertThreadMethod
{
   // get your information here

   performSelectorOnMainThread:@selector(loadAlert) withObject:nil waitUntilDone:NO
}
于 2012-06-21T22:11:34.560 回答