viewDidLoad中的DispatchQueue.main.async {}

时间:2017-05-31 19:42:45

标签: ios swift asynchronous concurrency grand-central-dispatch

我想知道如果我从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")
}

给出这些照片:

First selector fired
1
2
3
4
5
6
7
8
9
10
Third selector fired
Second selector fired

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

1 个答案:

答案 0 :(得分:7)

我曾经问similar question。让我引用我得到的答案的重要部分:

  

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

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

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