RunLoop與全局隊(duì)列

寫出以下代碼段在控制臺的輸出, 并解釋為什么?

- (void)viewDidLoad {

? ? [super viewDidLoad];

? ? dispatch_async(dispatch_get_global_queue(0, 0), ^{

? ? ? ? NSLog(@"before perform");

? ? ? ? [self performSelector:@selector(printLog) withObject:nil afterDelay:0];

? ? ? ? NSLog(@"after perform");

? ? });

}


- (void)printLog

{

? ? NSLog(@"printLog");

}

答案: 只會輸出beform perform 以及 after perform

涉及技術(shù)棧: GCD全局隊(duì)列, performSelector實(shí)現(xiàn)原理以及 Runloop的了解


原理:?

1. GCD默認(rèn)的全局并發(fā)隊(duì)列, 在執(zhí)行任務(wù)的時候, 會從線程池獲取可執(zhí)行任務(wù)的線程, 如果沒有就阻塞(子線程)

2.performSelector的實(shí)現(xiàn)原理是設(shè)置一個timer到當(dāng)前的runloop中, 并且mode為NSDefaultRunLoopMode

3.子線程的runloop默認(rèn)不啟動


進(jìn)階答案: 如何加一行代碼使得printLog正常輸出


進(jìn)階解法: 1. 切入點(diǎn) 原理三: ?既然子線程的runloop默認(rèn)不啟動, 那么我們就在performSelector將timer加入currentRunloop中之后 [[NSRunLoop CurrentRunLoop] run]; 啟動子線程的runloop 就可以正常輸出了

- (void)viewDidLoad {

? ? [super viewDidLoad];

? ? dispatch_async(dispatch_get_global_queue(0, 0), ^{

? ? ? ? NSLog(@"before perform");

? ? ? ? [self performSelector:@selector(printLog) withObject:nil afterDelay:0];

? ? ? ? [[NSRunLoop currentRunLoop] run];

? ? ? ? NSLog(@"after perform");

? ? });

}

2. 思路二: 可以將performSelector放入主線程(此方法會影響printLog輸出順序)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • runtime 和 runloop 作為一個程序員進(jìn)階是必須的,也是非常重要的, 在面試過程中是經(jīng)常會被問到的, ...
    made_China閱讀 1,226評論 0 7
  • 來源:擊水湘江 鏈接:http://www.lxweimin.com/p/536184bfd163 實(shí)例化講解Run...
    __Lex閱讀 271評論 0 2
  • RunLoop 文章目錄 RunLoop簡介 1.1 什么是RunLoop? 1.2 RunLoop和線程 1.3...
    May_d8f1閱讀 300評論 0 1
  • runtime 和 runloop 作為一個程序員進(jìn)階是必須的,也是非常重要的, 在面試過程中是經(jīng)常會被問到的, ...
    SOI閱讀 21,848評論 3 63
  • 一、什么是runloop 字面意思是“消息循環(huán)、運(yùn)行循環(huán)”。它不是線程,但它和線程息息相關(guān)。一般來講,一個線程一次...
    WeiHing閱讀 8,173評論 11 111