詳解RunLoop之面試題

本文首發於我的博客html

回顧詳解RunLoop之源碼分析中提出的問題

  • 什麼是Runloop
  • ios程序中 main函數爲何不會退出
  • runloop和線程的關係?
  • 程序中添加每3秒響應一次的NSTimer,當拖動tableview時timer可能沒法響應要怎麼解決?
  • runloop內部實現邏輯?
  • runloop 是怎麼響應用戶操做的, 具體流程是什麼樣的?
  • 說說runLoop的幾種狀態
  • runloop的mode做用是什麼?
  • 如何實現一個常駐線程

什麼是Runloop

  • Runloop 仍是比較顧名思義的一個東西,說白了就是一種循環,只不過它這種循環比較高級。通常的 while 循環會致使 CPU 進入忙等待狀態,而 Runloop 則是一種「閒」等待,這部分能夠類比 Linux 下的 epoll。當沒有事件時,Runloop 會進入休眠狀態,有事件發生時, Runloop 會去找對應的 Handler 處理事件。Runloop 可讓線程在須要作事的時候忙起來,不須要的話就讓線程休眠
  • RunLoop是經過經過內部維護的時間循環來對事件/消息進行管理的一個對象
    • 沒有消息須要處理時,休眠避免掉資源佔用
      • 用戶態 -> 內核態
    • 有消息時候,馬上被喚醒
      • 內核態 -> 用戶態
        image.png

ios程序中 main函數爲何不會退出

  • main函數內部調用 UIApplicationMain 這個方法會啓動一個RunLoop,有事作就作事,沒事作就等待,保持不會退出

runloop和線程的關係?

+ 每條線程都有惟一的一個與之對應的RunLoop對象
+ RunLoop保存在一個全局的Dictionary裏,線程做爲key,RunLoop做爲value
+ 線程剛建立時並無RunLoop對象,RunLoop會在第一次獲取它時建立
+ RunLoop會在線程結束時銷燬
複製代碼

runloop內部實現邏輯?

就是下圖所示的,用本身話總結出來就好 ios

image.png

程序中添加每3秒響應一次的NSTimer,當拖動tableview時timer可能沒法響應要怎麼解決?

  • 常見的2種Modegit

  • kCFRunLoopDefaultMode(NSDefaultRunLoopMode):App的默認Mode,一般主線程是在這個Mode下運行github

  • UITrackingRunLoopMode:界面跟蹤 Mode,用於 ScrollView 追蹤觸摸滑動,保證界面滑動時不受其餘 Mode 影響app

  • common模式下(一個佔位用的Mode,不是一種真正的Mode) 能夠兼容以上兩種模式函數

runloop 是怎麼響應用戶操做的, 具體流程是什麼樣的?

  • source1 捕捉用戶觸摸事件
  • source0去處理觸摸時間

說說runLoop的幾種狀態

  • kCFRunLoopEntry = (1UL << 0), // 即將進入Loop
  • kCFRunLoopBeforeTimers = (1UL << 1), //即將處理Timer
  • kCFRunLoopBeforeSources = (1UL << 2), //即將處理Source
  • kCFRunLoopBeforeWaiting = (1UL << 5), //即將進入休眠
  • kCFRunLoopAfterWaiting = (1UL << 6), //剛從休眠中喚醒
  • kCFRunLoopExit = (1UL << 7), //即將退出Loop
  • kCFRunLoopAllActivities = 0x0FFFFFFFU //全部狀態改變

runloop的mode做用是什麼?

  • 簡單來講就是不一樣模式隔離開來,保證同一種摸下下運行,source0,source1,timer,observer 的運行更流暢

如何實現一個常駐線程

簡單來講就是oop

  • 建立RunLoop
  • 像RunLoop中添加port、source等來保證RunLoop不退出
  • 啓動RunLoop

本文相關代碼github地址 github源碼分析

本文參考資料:spa

RunLoop官方源碼線程

iOS底層原理

更多資料,歡迎關注我的公衆號,不定時分享各類技術文章。

相關文章
相關標籤/搜索