RunLoop機制理解

2021-09-23 21:33:31 字數 3308 閱讀 3201

一、淺識runloop

runloop在開發中我們一直在用,但是沒有注意他。要想理解runloop,首先我們需要先了解一下程式執行機制。

二、runloop與執行緒的關係

runloop是用來管理執行緒的。每乙個執行緒都有乙個runloop物件。可以通過具體的方法去獲得。但是需要注意:雖然每乙個執行緒都可以獲取runloop物件,但是並不是每乙個執行緒中都有例項物件,我們可以這樣理解:如果我們不獲取runloop,這個runloop就不存在,我們獲取時,如果不存在,就會去建立。在主線程中,這個mainrunloop是預設建立並執行啟用的。

三、nsrunloop

nsrunloop是cocoa框架中的類,與之對應的是在core fundation中有乙個cfrunloopref類。這兩者的區別是前者不是執行緒安全的,而cfrunloopref是執行緒安全的。

1、獲取主線程的nsrunloop

//

獲取主線程的nsrunloop

+(nsrunloop *)mainrunloop;

2、獲取當前執行緒的nsrunloop

//

獲取當前執行緒的runloop:有的話就直接獲取,沒有的話就自動建立

+(nsrunloop *)currentrunloop;

3、nsrunloop的執行模式

//

獲取當前runloop的執行模式

@property(readonly,copy)nsstring *currentmode;

//兩種執行模式

//預設的模式,接收大部分輸入源的響應

nsstring *const

nsdefaultrunloopmode;

//多種模式的集合

nsstring *const nsrunloopcommonmodes;

4、獲取runloop的cfrunloopref物件

//

獲取runloop的cfrunloopref物件

-(cfrunloopref)getcfrunloop;

5、將定時器新增到runloop中

//

將定時器新增到runloop中

-(void)addtimer:(nstimer *)timer formode:(nsstring *)mode;

6、獲取下個響應時間

-(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中,nsport物件可以理解為詳細的載體,會傳遞訊息與其**。

- (void)removeport:(nsport *)aport formode:(nsstring *)mode;

將某個輸入源埠移除

四、runloop的呼叫

一般情況下我們很少去顯式呼叫或者啟動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 ...