我們創(chuàng)建一個異步線程菱父,然后在異步線程中添加了一個定時器或者 self.perform( with: afterDelay: )
時颈娜,等時間到了,卻發(fā)現(xiàn)沒有響應對應的方法浙宜。
@objc func doPerform() {
DispatchQueue.init(label: "com.perform.queue").async {
self.perform(#selector(self.performAction(objc1:)), with: "1", afterDelay: 3)
}
}
@objc func performAction(objc1:Any) {
print(objc1)
}
原因是:在iOS中,不管是用Timer也好蛹磺,還是使用perfor afterDelay
方法也好粟瞬,其本質(zhì)都是會創(chuàng)建一個定時器。而定時器的工作原理萤捆,就是添加到runloop中裙品,靠事件驅(qū)動來循環(huán)觸發(fā)的。所以俗或,這個觸發(fā)條件的核心就是runloop必須要在運行市怎。其實在每一條線程里面,都包含了一個runloop辛慰。但是呢区匠,只有在主線程里面的runloop是默認開啟的,其他子線程的runloop是要我們?nèi)ナ謩娱_啟的帅腌。這也就是為什么我們直接在主線程中添加一個定時器驰弄,就可以直接運行,而在異步線程中速客,卻出現(xiàn)無法響應的問題戚篙。
解決方法:
讓異步線程里面的runloop跑起來:
@objc func doPerform() {
DispatchQueue.init(label: "com.perform.queue").async {
print(Thread.current)
self.perform(#selector(self.performAction(objc1:)), with: "1", afterDelay: 3)
RunLoop.current.run()
}
}
@objc func performAction(objc1:Any) {
print(objc1)
}
打印信息
<NSThread: 0x60000300c1c0>{number = 5, name = (null)}
1