Run Loop 是與進程相關(guān)的基礎(chǔ)設(shè)施欢伏。Run Loop 是來協(xié)調(diào)待接受的事件、安排調(diào)度的亿乳,事件處理循環(huán)硝拧。Run Loop 的作用就是径筏,有任務(wù),開起進程障陶,沒任務(wù)滋恬,休眠進程。
翻譯自蘋果的 runloop 文檔
上一段代碼 抱究,與 NSRunLoop 和 NSThread 相關(guān)恢氯,
NSThread* th=[[NSThread alloc] initWithTarget:self selector:@selector(someMethod) object:nil];
[th start];
-(void) someMethod
{
NSLog(@"operation");
}
Run Loop 是處理 sockets 網(wǎng)絡(luò), ports 端口, files 文件 , keyboard 鍵盤 , mouse 鼠標(biāo) , timers 計時器 的機制的一層抽象。
NSThread 都有著專屬的 Run Loop 鼓寺,可以通過 currentRunLoop 方法訪問勋拟。
一般是不需要直接訪問 Run Loop 的÷韬颍可以用網(wǎng)絡(luò)相關(guān)的組件指定Run Loop 敢靡, 處理 IO 輸入輸出。
等著輸入源有數(shù)據(jù) / 事件苦银,給定線程的 Run Loop 就會讓合適的輸入處理函數(shù)處理有數(shù)據(jù) / 事件啸胧,等待執(zhí)行的輸入源。
執(zhí)行完后幔虏,Run Loop 會還原纺念。如果有其他輸入源的數(shù)據(jù) / 事件, 該線程的 Run Loop 會處理想括;如果無陷谱, 該線程會進入休眠狀態(tài)。
以上是抽象后的簡單描述瑟蜈,省略了很多細(xì)節(jié)叭首。
繼續(xù)解釋:
run loop 是不是只能在線程內(nèi)部訪問,執(zhí)行踪栋?
是的。 NSRunLoop 不是線程安全的图毕。所以只在跑這個 run loop 的線程的上下文中獲取比較好夷都。
來一個簡單地給 run loop 添加事件的例子?
上 ?? :
如果想要監(jiān)聽 port , 添加該 port 到 run loop 就可以了予颤,這個 run loop 就會監(jiān)聽該 port 的活動囤官,
- (void)addPort:(NSPort *)aPort forMode:(NSString *)mode
也可以直接給 run loop 添加計時器,
- (void)addTimer:(NSTimer *)aTimer forMode:(NSString *)mode
Run Loop 會還原蛤虐,什么意思党饮?
每一次迭代中,run loop 會按照他的 mode ,處理所有的條件滿足的事件驳庭。這個問題與 run loop 的 mode 相關(guān)刑顺,要看文檔氯窍。
開線程的時候,Run Loop 沒有被喚醒?
大多應(yīng)用蹲堂,主線程的 Run Loop 自動去跑狼讨。
人為開的線程,要去開啟對應(yīng)的 Run Loop 柒竞,響應(yīng)傳入的事件政供。
{
所以, 開線程朽基,用 timer ,需要手動開啟對應(yīng)的 Run Loop
}
能不能在線程外布隔,給線程的 Run Loop 添加事件?
什么意思哈?
不是給 Run Loop 添加事件稼虎。是在持有 Run Loop 的線程中衅檀,添加輸入源,例如計時器事件源渡蜻。該 Run Loop 就會監(jiān)聽事件源的活動术吝。
輸入的數(shù)據(jù)可以來自其他的線程 / 進程。處理輸入的 Run Loop 是監(jiān)聽這些事件源的 Run Loop 茸苇,跑在線程上排苍。
是不是,有時候可以用 Run Loop 堵塞線程一會学密?
是的淘衙。事件處理返回前, Run Loop 會駐留處理事件腻暮。任意 app 中彤守,都會輕易發(fā)現(xiàn)這點。任意的IO操作中哭靖,例如點擊按鈕具垫,加一個睡眠函數(shù)。方法完成了试幽,主 Run Loop 就被阻塞了筝蚕,整個 UI 都掛了。
任何的 Run Loop 中铺坞,都適用起宽。
Run, RunLoop, Run! RunLoop , 跑起來
交互性的應(yīng)用與命令行程序的區(qū)別,就是 RunLoop . 使用命令行程序济榨, 先配參數(shù)開起坯沪,執(zhí)行命令,就結(jié)束了擒滑。交互性的應(yīng)用等待用戶輸入腐晾,給用戶反饋叉弦,然后一直等。很多長周期的進程中赴魁,都有這種機制卸奉。舉個經(jīng)典的例子,服務(wù)端中的
while( 1 ){ select( ); }
...
CFRunLoop 中最重要的特性是 CFRunLoopModes , RunLoop 的模態(tài)颖御。 RunLoop 處理 Run Loop Sources , Run Loop 的事件源榄棵。事件源登記在 Run Loop 的一到多個模態(tài)上。 Run Loop 必須在一個給定模態(tài)上跑潘拱。事件源新加了事件疹鳄,只要當(dāng)該事件源與Run Loop 當(dāng)前的模態(tài)一致,Run Loop 才處理該事件芦岂。
Mode 分為不同的模式瘪弓, Common, UITracking ... , 也是一種狀態(tài)。 個人覺得禽最,可以叫模態(tài)腺怯。
建議閱讀 Run Loop 文檔,https://developer.apple.com/documentation/foundation/nsrunloop
線程中 Run Loop 的應(yīng)用川无,
說明: 為了有意思一些呛占, 我采取了意譯。
本文翻譯自
Stack Over Flow Understanding NSRunLoop
蘋果的 runloop 文檔