一、淺識runloop
runloop在開發中我們一直在用,但是沒有注意他。要想理解runloop,首先我們需要先了解一下程式執行機制。
二、runloop與執行緒的關係
runloop是用來管理執行緒的。每乙個執行緒都有乙個runloop物件。可以通過具體的方法去獲得。但是需要注意:雖然每乙個執行緒都可以獲取runloop物件,但是並不是每乙個執行緒中都有例項物件,我們可以這樣理解:如果我們不獲取runloop,這個runloop就不存在,我們獲取時,如果不存在,就會去建立。在主線程中,這個mainrunloop是預設建立並執行啟用的。
三、nsrunloop
nsrunloop是cocoa框架中的類,與之對應的是在core fundation中有乙個cfrunloopref類。這兩者的區別是前者不是執行緒安全的,而cfrunloopref是執行緒安全的。
1、獲取主線程的nsrunloop
//2、獲取當前執行緒的nsrunloop獲取主線程的nsrunloop
+(nsrunloop *)mainrunloop;
//3、nsrunloop的執行模式獲取當前執行緒的runloop:有的話就直接獲取,沒有的話就自動建立
+(nsrunloop *)currentrunloop;
//4、獲取runloop的cfrunloopref物件獲取當前runloop的執行模式
@property(readonly,copy)nsstring *currentmode;
//兩種執行模式
//預設的模式,接收大部分輸入源的響應
nsstring *const
nsdefaultrunloopmode;
//多種模式的集合
nsstring *const nsrunloopcommonmodes;
//5、將定時器新增到runloop中獲取runloop的cfrunloopref物件
-(cfrunloopref)getcfrunloop;
//6、獲取下個響應時間將定時器新增到runloop中
-(void)addtimer:(nstimer *)timer formode:(nsstring *)mode;
-(nsdate *)limitdateformode:(nsstring *)mode;定時器的執行,其實並不是按照時間段額間隔進行呼叫方法,而是在定時器註冊到runloop中後,runloop會設定乙個乙個的時間點進行呼叫,例如,5,10,15,20等等。如果錯過了某個時間點,定時器並不會延遲呼叫,而是直接等待下乙個時間點呼叫,所以定時器並不是準確的。
7、在某個時間期限前接收相應
-(void)aceptinputformode:(nsstring *)mode beforedate:(nsdate *)limitdate;8、開始執行
-(void)run;9、到某個時間點執行
-(void)rununtildate:(nsdate *)limitdate;10、在某個期限前執行
-(bool)runmode:(nsstring *)mode beforedate:(nsdate *)limitdate;11、
- (void)addport:(nsport *)aport formode:(nsstring *)mode;四、runloop的呼叫新增輸入源埠到runloop中,nsport物件可以理解為詳細的載體,會傳遞訊息與其**。
- (void)removeport:(nsport *)aport formode:(nsstring *)mode;
將某個輸入源埠移除
一般情況下我們很少去顯式呼叫或者啟動runloop,但是下邊的情況需要手動設定。
1、在分執行緒中使用定時器
定時器的實現是基於runloop的,平時我們使用定時器或許並沒有對runloop做什麼操作,那是因為主線程的runloop預設是開啟執行的,如果我們進行如下操作:
-(void)viewdidload);
}-(void
)time
[[nsrunloop currentrunloop] run];這樣定時器才可以正常工作。
2、當執行緒中使用如下的方法時
某些延遲函式和選擇器在分執行緒中的使用,我們必須手動開始runloop
@inte***ce五、其他nsobject (nsdelayedperforming)
- (void)performselector:(sel)aselector withobject:(id)anargument afterdelay:(nstimeinterval)delay inmodes:(nsarray *)modes;
- (void)performselector:(sel)aselector withobject:(id
)anargument afterdelay:(nstimeinterval)delay;
+ (void)cancelpreviousperformrequestswithtarget:(id)atarget selector:(sel)aselector object:(id
)anargument;
+ (void)cancelpreviousperformrequestswithtarget:(id
)atarget;
- (void)performselector:(sel)aselector target:(id)target argument:(id)arg order:(nsuinteger)order modes:(nsarray *)modes;
- (void)cancelperformselector:(sel)aselector target:(id)target argument:(id
)arg;
- (void)cancelperformselectorswithtarget:(id)target;
輸入源被註冊到runloop中時會有方法進行remove。但是定時器沒有remove,但是它的invalidate方法可以將其從runloop中移除。invalidate是重要的也是唯一的將定時器從runloop中登出的方法,所以如果我們建立了定時器,就一定要再不適用的時候呼叫invalidate方法。
六、附參考自:
IOS 多執行緒 RUNLOOP 機制 二
二,何時使用run loop 對於輔助線程,在需要和執行緒有更多互動時,才使用run loop。比如 1 使用埠或者自定義輸入源來和其他執行緒通訊 2 使用執行緒定時器 3 cocoa中使用任何performselector.的方法 參考 table performing selectors on ...
RunLoop處理邏輯
如圖是從蘋果官方文件擷取下來的runloop處理邏輯流程圖,runloop處理邏輯過程為 1.通知observer即將進入loop 2.通知observer 即將處理timer 3.通知observer將要處理source0 4.處理source0 5.如果有source1,跳到第9步 6.通知ob...
多執行緒篇 RunLoop
簡述 1 runloop是事件接收和分發機制的乙個實現 3 以及節省cpu資源,提高程式效能 該做事時做事,該休息時休息 如何獲取runloop物件 這裡的話ios提供了兩套api來訪問或使用runloop 1 cfrunloopref 是在 corefoundation 框架內的,它提供了純 c ...