viewDidLoad中的DispatchQueue.main.async {}

Yur*_*nov 6 concurrency asynchronous grand-central-dispatch ios swift

我想知道如果我从viewDidLoad方法在主队列中异步调用某些内容会发生什么.一个小实验向我展示了这些结果:

这段代码:

override func viewDidLoad() {
    super.viewDidLoad()

    firstSelector()
    DispatchQueue.main.async {
        self.secondSelector()
    }
    for i in 1...10 {
        print(i)
    }
    thirdSelector()

}

func firstSelector() {
    print("First selector fired")
}

func secondSelector() {
    print("Second selector fired")
}

func thirdSelector() {
    print("Third selector fired")
}
Run Code Online (Sandbox Code Playgroud)

给出这些印刷品:

First selector fired
1
2
3
4
5
6
7
8
9
10
Third selector fired
Second selector fired
Run Code Online (Sandbox Code Playgroud)

所以最后一个被调用的方法是secondSelector.我认为这是因为主队列是串行的,当我异步调用某个方法(在本例中为secondSelector)时,它立即返回并等待直到所有其他方法都完成.在队列没有任务之后,它完成了我异步调用的方法.我的想法是对的吗?

Sta*_*ich 9

我曾经问过类似的问题.让我引用我得到的答案的重要部分:

"因为主线程上的默认runloop具有特殊的行为,在运行时,它还会处理主调度队列..."

当您执行dispatch_async主线程时,您的块{ self.secondSelector() }将被安排到主运行循环.由于viewDidLoad主运行循环已经在执行方法,因此将执行您的调度块以及在viewDidLoad块之前调度的所有其他(可能的)块或方法.

请记住,您的问题是关于dispatch_async从主线程调度到主队列和主运行循环的行为.viewDidLoad有没有什么关系呢-它是与此有关的唯一的事情,是UIViewController的生命周期方法,如viewDidLoad,viewWillAppear等都是主线程(由主运行循环处理)在所有运行.除了viewDidLoad在主线程上运行此方法之外,您将看到与任何方法相同的行为.如果从其他线程调用dispatch_async,您可能会对不同的结果感到惊讶,因为在这种情况下,您将有两个线程同时工作(您的另一个线程和您调度的主线程).