今天是今年的最后一天班,簡書活動的第二篇文章,我就寫一篇工作方面的技術文章吧。主題也很符合我們的生活:NSRunLoop運行循環,就像我們的生活一樣,一年一年的循環。
學習RunLoop,主要就是要研究Core Foundation框架下的CFRunLoopRef類以及相關類,因為NSRunLoop就是基于Core Foundation框架下的CFRunLoopRef進一步封裝而來的。
//蘋果官方對RunLoop的圖解
1.主要學習Core Foundation中關于RunLoop的5個類
CFRunLoopRef;// RunLoop對象
CFRunLoopModeRef;// 運行模式
CFRunLoopSourceRef;// 輸入源,可以理解為交互
CFRunLoopTimerRef;// 定時器,可以理解為NSTime
CFRunLoopObserverRef;// 觀察者,監聽RunLoop的狀態
2.CFRunLoopModeRef代表RunLoop的運行模式
1)一個 RunLoop 包含若干個 Mode,每個Mode又包含若干個Source/Timer/Observer
2)每次RunLoop啟動時,只能指定其中一個 Mode,這個Mode被稱作 CurrentMode
3)如果需要切換Mode,只能退出Loop,再重新指定一個Mode進入
4)這樣做主要是為了分隔開不同組的Source/Timer/Observer,讓其互不影響
系統默認注冊了5個Mode:
1)kCFRunLoopDefaultMode:App的默認Mode,通常主線程是在這個Mode下運行
2)UITrackingRunLoopMode:界面跟蹤 Mode,用于 ScrollView 追蹤觸摸滑動,保證界面滑動時不受其他 Mode 影響
3)UIInitializationRunLoopMode: 在剛啟動 App 時第進入的第一個 Mode,啟動完成后就不再使用
4)GSEventReceiveRunLoopMode: 接受系統事件的內部 Mode,通常用不到
5)kCFRunLoopCommonModes: 這是一個占位用的Mode,不是一種真正的Mode
3.CFRunLoopSourceRef
CFRunLoopSourceRef是事件源(輸入源)
以前的分法
Port-Based Sources // 端口,可以理解為系統內部的
Custom Input Sources // 自定義的輸入源,比如手勢之類的
Cocoa Perform Selector Sources // 調用的performSelector之類的方法
現在的分法
Source0:非基于Port的
Source1:基于Port的
4.CFRunLoopTimerRef是基于時間的觸發器
基本上說的就是NSTimer,還有GCD中的定時器
5.CFRunLoopObserverRef
CFRunLoopObserverRef是觀察者,能夠監聽RunLoop的狀態改變
kCFRunLoopEntry = (1UL << 0), 即將進入runloop
kCFRunLoopBeforeTimers = (1UL << 1),// 即將處理timer事件
kCFRunLoopBeforeSources = (1UL << 2),//即將處理source事件
kCFRunLoopBeforeWaiting = (1UL << 5),//即將進入睡眠
kCFRunLoopAfterWaiting = (1UL << 6), //被喚醒
kCFRunLoopExit = (1UL << 7), // runloop退出
kCFRunLoopAllActivities = 0x0FFFFFFFU // 所有的狀態