0

我有 2 个带有 dispatch_sync 的块,当第一个块结束时,我为用户显示窗口并开始运行第二个块。但是在第二个区块结束之前,我不会点击屏幕上的任何按钮..

看代码:

[HUD showUIBlockingIndicatorWithText:@"Loading..."];
dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^ {
        dispatch_sync(dispatch_get_main_queue(), ^{
                [UIView beginAnimations:@"fade" context:nil];
                [UIView setAnimationDuration:0.5];
                self.capa.alpha = 0.0;
                [UIView commitAnimations];
                [HUD hideUIBlockingIndicator];
        });
});

dispatch_barrier_async(queue, ^ {
    //code executed in the background
    dispatch_async(dispatch_get_main_queue(), ^{
        NSLog(@"entrou na foto");
        //[self getFotos];
    });
});
4

3 回答 3

1

如果你在主线程上调用任何代码,它会阻塞你的 UI,所以调用

dispatch_async(dispatch_get_main_queue(), ^{
    NSLog(@"entrou na foto");
    [self getFotos];
});

将阻止您的 UI 直到[self getFotos]返回。

于 2013-05-25T22:30:19.410 回答
0

您可能想在此处使用调度组。在禁用 UI 的情况下将块发送到后台并发送到组中,然后您可以生成一个等待线程调用 dispatch_group_wait 阻塞它,直到任务完成以重新启用 UI。只有禁用的部分被锁定。其他一切都会奏效

dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, /* queue */, ^{ /* ... */ });
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
               ^{
                   dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
                   // This thread will be blocked until background tasks are done.
                   dispatch_async(dispatch_get_main_queue(),
                   ^{ /* ... */ });
               });
于 2013-06-05T20:55:24.363 回答
0

几个反应。

  1. 您在这里使用的模式不太有意义。从您的代码示例中做出一些推论,我原以为所需的模式是:

    • 只需在主队列中启动 HUD(或一些旋转活动指示器视图);

    • 在后台队列中调度所有单独的耗时进程;如果它们可以同时运行,您将使用dispatch_async您的queue; 和

    • 完成您的完成块的最后一个dispatch_barrier_async(即您指示分派到并发队列的所有其他块都已完成),这会dispatch_async(通常不是sync)返回主队列以停止 HUD。

  2. 此代码示例中没有任何内容可以暗示任何会使您的 UI 无响应的内容,因此为了清晰/简洁起见,我不得不怀疑您已删除的代码部分中的某些内容。一般来说,有两件事可能会使您的 UI 无响应:

    • 显然,如果有任何东西被分派回主队列,那是很慢的。例如,你有一个getFotos方法,但我们不知道它是做什么的,但如果它很慢,就会导致问题。在您的代码段的这一类中显然没有任何内容,但这是需要注意的一类问题。

    • 更微妙的问题可能是,如果其中有一些与 UI 相关的内容意外滑入该后台队列。具有讽刺意味的是,这通常会导致 UI 冻结一段时间。您必须分享您在发送到后台的那个区块中所做的事情的详细信息,以便我们进一步为您提供建议。

    但这是仅有的两件事让我突然想到可能导致您的 UI 暂时无响应。


与您的性能问题完全无关,但我通常不建议使用旧式动画。正如文档所说,“......在 iOS 4.0 及更高版本中不鼓励使用此方法。” 所以我建议删除那些说:

[UIView beginAnimations:@"fade" context:nil];
[UIView setAnimationDuration:0.5];
self.capa.alpha = 0.0;
[UIView commitAnimations];

相反,我建议您使用基于块的动画,例如:

[UIView animateWithDuration:0.5 animations:^{
    self.capa.alpha = 0.0;
}];
于 2013-05-26T02:09:31.300 回答