iOS 設置 延遲執行 與 取消延遲執行 方法 以及對 run loop 初步認識


之前開發過程中經常會有需求會使用 NSObject中的"performSelector:withObject:afterDelay:"做方法延遲執行的處理, 但是 還沒有什么地方需要實現 取消 這個延遲執行方法"cancelPreviousPerformRequestsWithTarget:".(具體可參見系統庫文件 NSOject里面兩個方法的聲明).

但是 我們應該知道在什么條件下,合理使用 延遲 與 取消延遲.

延遲 和 取消延遲 應該 在同一個 事件處理循環(Run loop)里,不然 是無法取消的. (之前 不知道 啥叫 Run loop 哭~ 因為突然要使用 取消延遲執行的方法 才了解到的)

Run loop :一般程序至少有一個線程,那么這個線程是主線程, 而這個線程上會有一個 runloop(負責所有主線程的事件,包括UI事件) 一直在循環,就是我理解的事件處理循環,它會一直監聽 是否有相應的觸發動作(人為也好,內部機制也好),有則會立即做出對對應消息的響應,沒有則處於等待狀態甚至休眠.那么 我可以說 這個 run loop  是依附在對應的線程里面的.它的生命周期隨着線程的啟動終止等變化而變化.

在 蘋果官方文檔里還有示意圖,詳細講解,我理解的"觸發動作"即 "源事件"

    Runloop接收兩種源事件:input sources和timer sources。

     input sources 傳遞異步事件,通常是來自其他線程和不同的程序中的消息;(基於端口的輸入源,自定義輸入源,Cocoa上的Selector源)

     timer sources(定時器) 傳遞同步事件(重復執行或者在特定時間上觸發)。//如果要設定NSTimer 要在當前的Run loop 里設定(一般在主線程里),在子線程里面設置NSTime,要獲取子線程的Run loop,才有效 "[[NSRunLoop currentRunLoop] addTimer:.....]"

那我今天用到的 "延遲 和 取消延遲"也是一種定時器,應該屬於"timer sources(定時器) "類型的"源事件".所以也要在當前線程的Run loop里面處理這個問題

描述一下,我使用 延遲 和取消延遲的使用場景:

在播放視頻的過程中, 點擊屏幕時候 要展示菜單,如果無其他操作,菜單自動消失,如果是再單點擊屏幕則菜單被手動觸發消失.

那么在整個交互邏輯的過程中,從展示菜單那一刻起,添加 "延遲方法" ,如果是單點屏幕取消菜單,則要"取消延遲".

代碼如下:

[self performSelector:@selector(onClickOverlay:) withObject:nil afterDelay:DelayTimeSeconds];
//延遲
[NSObject cancelPreviousPerformRequestsWithTarget:self]; //這個是取消當前run loop 里面所有未執行的 延遲方法(Selector Sources)
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(onClickOverlay:) object:nil];// @selector 和 object 都和 延遲一致 就是 指定取消 未執行的一條或者多條的延遲方法.
 

 

參考文章

iOS 官方 runloop (先看這個 最重要)

https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html

認識runloop

http://www.jianshu.com/p/613916eea37f

runloop 詳解

http://blog.csdn.net/ztp800201/article/details/9240913

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM