为什么dispatch_async块阻塞?

时间:2017-02-22 14:14:40

标签: objective-c multithreading asynchronous dispatch-async

viewDidAppear内部,我正在使用以下代码:

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

这阻止了用户界面。我期待这个5秒的睡眠在后台运行。我错过了什么?

2 个答案:

答案 0 :(得分:1)

请使用performSelector作为下面给出的演示。它在后台给定时间间隔后执行某些方法,不会阻止主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
}

答案 1 :(得分:0)

通过让线程在后台睡眠,我不清楚你想要完成什么。你打算在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,你不必记住你正在使用的线程修改