为什么 dispatch_async block 阻塞了?

why is dispatch_async block blocking?

viewDidAppear 中,我将输入以下代码:

dispatch_async(dispatch_get_main_queue(), ^{
        [NSThread sleepForTimeInterval:5.0f];
        }
});

这会阻塞 UI。我原以为这 5 秒会在后台休眠到 运行。我错过了什么?

请按照下面给出的演示使用 performSelector。它在给定的时间间隔后在后台执行一些方法并且不阻塞 main UI.

- (void) viewDidAppear:(BOOL)animated
{
    [super viewDidAppear: animated];

    [self performSelector:@selector(someMethod) withObject:nil afterDelay:5];
}


- (void) someMethod{
   // some code statements to run after 5 seconds
}

我不清楚你想让线程在后台休眠是想达到什么目的。 5 秒后你要 运行 一些代码吗?你有几个选择。

1) 使用dispatch_after代替dispatch_async。以下代码将在指定延迟后在主线程上 运行。如果您开始在 Xcode 中输入此内容,它应该会为您提供一个自动完成片段。只需在完成块中做任何你需要做的事情,包括 UI 东西,因为你将在主线程上。

- (void)viewDidAppear {
    [super viewDidAppear];
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSLog(@"5 seconds have passed");
    });
}

2) 在非主线程上使用dispatch_async。您可以使用上面编写但已修改的代码。如果您需要对 UI 做一些事情,您将需要另一个嵌套的异步块 运行 在主队列上。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    NSLog(@"You're now on a background thread");
    [NSThread sleepForTimeInterval:5.0f];
    NSLog(@"5 seconds have passed");
    dispatch_async(dispatch_get_main_queue(), ^{
        NSLog(@"Do UI stuff");
    })
});

除非您有某些特殊原因不这样做(运行在后台线程上执行繁重的操作),否则我会建议选项 #1,因为不必记住您在哪个线程会更容易如果您想进行 UI 修改。