中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何理解主線程與主Runloop

發布時間:2021-10-19 09:46:50 來源:億速云 閱讀:101 作者:iii 欄目:編程語言

這篇文章主要講解了“如何理解主線程與主Runloop”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“如何理解主線程與主Runloop”吧!

Pre

  • macOS:Catalina 10.15.7

  • Xcode:12.3

  • objc4:objc4-787.1

基本概念

CFRunloop

  1. CFRunLoop對象監視任務的輸入源,并在它們準備好進行處理時分派控制。

  2. 運行循環可以監視三種類型的對象:CFRunLoopSourceCFRunLoopTimerCFRunLoopObserver

  3. 添加到運行循環中的每個源、計時器和觀察者必須與一個或多個運行循環模式相關聯。

  4. Core Foundation定義了一種特殊的偽模式,稱為common modes,它允許您將多個模式與給定的source、timer或observer關聯起來。

  5. 每個線程只有一個運行循環。你既不創建也不銷毀線程的運行循環。Core Foundation會根據需要自動為您創建它。

  6. 運行循環可以遞歸地運行。您可以在任何運行循環調用中調用CFRunLoopRunCFRunLoopRunInMode,并在當前線程的調用堆棧上創建嵌套的運行循環激活。

  7. Cocoa應用程序構建在CFRunLoop之上,實現它們自己的高級事件循環。在編寫應用程序時,可以將源代碼、計時器和觀察者添加到它們的運行循環對象和模式中。然后,您的對象將作為常規應用程序事件循環的一部分被監視。使用NSRunLoop的gettcfrunloop方法可以得到對應的CFRunLoopRef類型。

NSRunloop

  • NSRunLoop是對Core Fundation中的CFRunloop的封裝

  • NSRunLoop對象處理來自窗口系統的鼠標和鍵盤事件、NSPort對象和NSConnection對象等源的輸入。NSRunLoop對象也會處理NSTimer事件。

  • 你的應用程序既不創建也不顯式管理NSRunLoop對象。每個NSThread對象(包括應用程序的主線程)都有一個根據需要自動創建的NSRunLoop對象。如果需要訪問當前線程的運行循環,可以使用類方法currentRunLoop來實現。

  • 注意,從NSRunLoop的角度來看,NSTimer對象不是“輸入”——它們是一種特殊的類型,這意味著當它們觸發時,不會導致運行循環返回。

  • NSRunLoop類通常被認為是線程不安全的,它的方法應該只在當前線程的上下文中被調用。永遠不要嘗試調用運行在不同線程中的NSRunLoop對象的方法,因為這樣做可能會導致意想不到的結果。

線程 & Runloop

先看結論!劃重點!

  • CocoaCore Foundation都提供了運行循環對象(NSRunloopCFRunloop)來幫助配置和管理線程的運行循環。

  • 應用程序不需要顯式地創建這些對象;每個線程(包括主線程)都有一個關聯的Runloop對象。

  • 作為應用程序啟動過程的一部分,應用程序框架自動在主線程上設置并運行運行循環。而子線程需要顯式地運行它們的運行循環。

  • 關系概括:App啟動后,蘋果在主線程創建了其關聯的Runloop,并在該Runloop中注冊兩個Observer

    • 第一個事件:BeforeWaiting(準備進入休眠),回調內會調用_objc_autoreleasePoolPop()釋放舊的池并調用_objc_autoreleasePoolPush()創建新的池

    • 第二個事件:Exit(即將退出Loop),回調內會調用_objc_autoreleasePoolPop()銷毀自動釋放池

    • 第一個Observer(優先級最高)監控的事件:Entry(即將進入Loop),回調內會調用_objc_autoreleasePoolPush()創建自動釋放池

    • 第二個Observer(優先級最低)監控兩個事件:

關系分析

  • 根據調用堆棧我們可以看出來,當調用UIApplicationMain()方法后,系統會自動為其創建相關聯的Runloop

  • 通過在main()函數首行即獲取主線程與主runloop可以看到:此時主線程的runloop已經存在了。我們可以推測出主線程創建后即會創建對應的runloop,也就是說,主runloop在程序一啟動就默認創建好了。 如何理解主線程與主Runloop 但是此時的主runloop中,還未添加相關觀察者等等。

  • 當代碼從main()開始執行,此時的runloop依然是一個空的結構體 如何理解主線程與主Runloop

  • 查看進入applicationDidLaunchingWithOptions:之前的調用堆棧 如何理解主線程與主Runloop 可以看到會為此時的主Runloop添加Source等相關信息

  • 走進applicationDidLaunchingWithOptions時,再通過po CFRunloopGetMain()獲取此時的主Runloop信息,可以看到觀察者、source等都已添加完成

// 截取部分
current mode = kCFRunLoopDefaultMode,
common modes = <CFBasicHash 0x6000014e5260 [0x7fff8002e8c0]>{type = mutable set, count = 2,
entries =>
	0 : <CFString 0x7fff806610e0 [0x7fff8002e8c0]>{contents = "UITrackingRunLoopMode"}
	2 : <CFString 0x7fff801ab7e8 [0x7fff8002e8c0]>{contents = "kCFRunLoopDefaultMode"}
}

感謝各位的閱讀,以上就是“如何理解主線程與主Runloop”的內容了,經過本文的學習后,相信大家對如何理解主線程與主Runloop這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

丽江市| 富宁县| 固原市| 屏山县| 六枝特区| 德江县| 瓮安县| 米泉市| 丹寨县| 许昌市| 东乌| 山东省| 罗平县| 东辽县| 平陆县| 白玉县| 图木舒克市| 沙河市| 宁远县| 洛隆县| 朔州市| 樟树市| 吴川市| 宁南县| 曲水县| 揭西县| 鄂州市| 嘉禾县| 安宁市| 嘉祥县| 宜昌市| 济宁市| 普宁市| 团风县| 顺平县| 三穗县| 望奎县| 丰宁| 安义县| 黔东| 石狮市|