【Rason的iOS每周小應(yīng)用】iOS之Runloop

  • Runloop的作用
    Runloop準(zhǔn)確來說控制的是線程的休眠和喚醒,是一套使線程持續(xù)運行的機制(而不是一下子跑完就沒了)

  • Runloop常見疑問

  1. Runloop是如何喚醒的?
    進入休眠后,并不是自己喚醒的,都是要借助外力(也就是其他線程換起的)。如觸摸事件,系統(tǒng)將觸摸封裝成事件,并且通過進程之間端口通訊傳遞到我們的進程。包括我們所熟知的定時器事件,必然也是系統(tǒng)給告訴我們的進程。
  2. 界面卡頓
    為什么界面卡頓?就是CPU和GPU渲染工作未完成,在屏幕刷新信號時,由于界面未渲染完成,顯示的還是上一張界面,所以看起來會卡頓。當(dāng)然在這里也有Runloop的原因,就是在每一次屏幕刷新之間,盡量耗時任務(wù)盡量移動到子線程執(zhí)行,無法移動的,盡量分成多個小任務(wù)。
  • Runloop如何運作?
  1. 存在輸入源,才能啟動Runloop,否則直接退出,往后執(zhí)行。
  2. 運行模式,其實只是將事件運行的環(huán)境進行分類。每次Runloop都會運行在指定的模式,只有當(dāng)前模式的事件,才會觸發(fā)。假設(shè)當(dāng)前運行模式是A,而添加了一個定時器到模式B,那么只有當(dāng)Runloop運行到模式B,那么定時器才會執(zhí)行。
  3. Runloop退出的條件是什么?①移除所有輸入源 ②主動停止Runloop
  • Runloop支持線程喚醒的事件類型
  1. 基于端口的事件
    如觸摸事件,系統(tǒng)將觸摸事件封裝,并且通過進程之間端口通訊傳遞到我們的進程。

    [[NSRunLoop currentRunLoop] addPort:port forMode:NSRunLoopCommonModes];
    
  2. 自定義事件

    [self performSelector:@selector(taskDo) onThread:thread withObject:nil waitUntilDone:NO modes:@[NSDefaultRunLoopMode]];
    
  3. 基于時間的定時事件

    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
    
  • Runloop的應(yīng)用
    1. UI在什么時候渲染?
      我們先來看一段。
      self.view.hidden = YES;
      ......
      self.view.hidden = NO;
      
      會不會閃一下?答案是不會的。因為UI不是立即渲染的,CA在runloop中注冊了一個即將進入休眠的observer,在休眠之前對已提交的請求進行集中渲染。
    2. 界面卡頓問題
      卡頓問題,一次runloop繪制任務(wù)太多仍會存在卡頓問題,放到下個Runloop,以減少單次runloop繪制任務(wù)。(其實重用UI、子線程處理耗時的非UI操作基本上能處理大多數(shù)常見卡頓)。runloop中將一個任務(wù)放到第二次runloop中執(zhí)行。最簡單使用[self performSelector:@selector(xxxxx) withObject:nil afterDelay:0],而GCD的話,是不一定的。
    3. 第三方動態(tài)化框架RN、Weex等
      這些框架能否都跑在主線程?可以是可以,但是由于流暢性考慮,都是管理自己的線程,自己的Runloop。最簡單的就是,添加一個NSPort?;睿缓笾苯优芫涂梢粤?。一些熱更新呢等處理,可以考慮停止線程、Runloop,釋放很多的內(nèi)存。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容