我想知道如果我从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)时,它立即返回并等待直到所有其他方法都完成。在队列没有任务之后,它完成了我异步调用的方法。我的想法是对的吗?
答案 0 :(得分:7)
我曾经问similar question。让我引用我得到的答案的重要部分:
“因为主线程上的默认runloop具有特殊行为,在运行时,它还会处理主调度队列......”
当您对主线程执行dispatch_async
时,您的块{ self.secondSelector() }
将被安排到主运行循环。由于主运行循环已经执行viewDidLoad
方法,因此将在viewDidLoad
之后处理您的调度块以及在执行块之前调度的所有其他(可能)块或方法。
请记住,当您从主线程调度到主队列和主运行循环时,您的问题是dispatch_async
的行为。 viewDidLoad
与它无关 - 这里唯一与之相关的是UIViewController
的生命周期方法,如viewDidLoad
,viewWillAppear
等都在主线程(由主运行循环处理)。鉴于此方法在主线程上运行,您将看到除viewDidLoad
以外的任何方法的相同行为。如果从其他线程调用dispatch_async,您可能会对不同的结果感到惊讶,因为在这种情况下,您将有两个线程同时工作(您的另一个线程和您调度的主线程)。