iOS 讓你認識RunLoop

2021-07-03 08:08:36 字數 3426 閱讀 7300

1. 什麼是runloop,他是幹什麼用的

runloop可以理解為cocoa下的一種訊息迴圈機制,用來處理各種訊息事件,我們在開發的時候並不需要手動去建立乙個runloop,因為框架為我們建立了乙個預設的runloop,通過[nsrunloop currentrunloop]我們可以得到乙個當前執行緒下面對應的runloop物件,不過我們需要注意的是不同的runloop之間訊息的通知方式。

run loop就是乙個事件處理的迴圈,用來不停的調動工作以及處理輸入事件。使用run loop的目的就是節省cpu效率,執行緒在有工作的時候忙於工作,而沒工作的時候處於休眠狀態。

2.runloop的幾種模式

每個run loop可執行在不同的模式下,乙個run loop mode是乙個集合,其中包含其監聽的若干輸入事件源,定時器,以及在事件發生時需要通知的run loop observers。執行在一種mode下的run loop

只會處理其run loop mode中包含的輸入源事件

,定時器事件

,以及通知run loop mode中包含的observers。

cocoa中的預定義模式有:

connection模式

定義:nsconnectionreplymode(cocoa)

描述:處理nsconnection物件相關事件,系統內部使用,使用者基本不會使用。

modal模式

定義:nsmodalpanelrunloopmode(cocoa)

描述:處理modal panels事件。

獲取當前執行緒的run loop mode

表1-1列出了cocoa和core foundation預先定義的模式。

表1-1

3,runloop 與 nstimer,nsurlconnection 

nstimer與nsurlconnection預設執行在default mode下,這樣當使用者在拖動uitableview處於uitrackingrunloopmode模式時,nstimer不能fire,nsurlconnection的資料也無法處理。

nstimer的例子:

在乙個uitableviewcontroller中啟動乙個0.2s的迴圈定時器,在定時器到期時更新乙個計數器,並顯示在label上。

-(void)viewdidload

- (void)incrementcounter:(nstimer *)thetimer

或[[nsrunloop currentrunloop] addtimer:timer formode:nsrunloopcommonmodes];

另外一種是放到nsthread中

- (void)viewdidload

- (void)newthread  

}- (void)timer_callback

- (void)incrementcounter:(nstimer *)thetimer

nsurlconnection也是如此,見sdwebimage中的描述,以及sdwebimage**********.m**中的實現。修改nsurlconnection的執行模式可使用scheduleinrunloop:formode:方法。

nsurlrequest *request = [[nsurlrequest alloc] initwithurl:url cachepolicy:nsurlrequestreloadignoringlocalcachedata timeoutinterval:15];

nsurlconnection *connection = [[[nsurlconnection alloc] initwithrequest:request delegate:self startimmediately:no]autorelease];

[connection scheduleinrunloop:[nsrunloop currentrunloop] formode:nsrunloopcommonmodes];

[connection start];

5 ,runloop 與 執行緒關係

學習iphone開發,autorelease的何時釋放一直是困擾我的乙個問題,總覺得大部分文件提到的延遲釋放,但是這個延遲感念非常模糊,5s叫延遲還是5min叫延遲?所以總覺得擔心我用到標明autorelease物件的時候由於它堅持不到已經被釋放了。最近查了一下autorelease到底什麼時候釋放,發現和runloop有關,再查runloop發現有一大堆的解釋,但是感覺大概意思就是runloop就是事件迴圈,事件包含了:觸屏,nstimer等,每個執行緒建立的時候都有乙個runloop迴圈,對於每乙個runloop, 系統會隱式建立乙個autorelease pool,這樣所有的release pool會構成乙個象callstack一樣的乙個棧式結構,在每乙個runloop結束時,當前棧頂的autorelease pool會被銷毀,這樣這個pool裡的每個object會被release。下面是具體解釋:

1.如果能夠真正的理解autorelease,那麼才是理解了objective c的記憶體管理。autorelease實際上只是把對release的呼叫延遲了,對於每乙個autorelease,系統只是把該object放入了當前的autorelease pool中,當該pool被釋放時,該pool中的所有object會被呼叫release。

實際上對於 [nsstring stringwithformat:1.0] 這類建構函式返回的物件都是autorelease的。

2. autorelease pool來避免頻繁申請/釋放記憶體(就是pool的作用了)。這個應該是相對比較好理解的。

總結:(1)一定要注意autorelease pool的生存週期,理解runloop,避免在物件被釋放後使用。

(2)[nsstring stringwithformat]這類函式返回的物件是不需要再自己release的,它已經被autorelease了, 如果你想把它當乙個全域性物件使用,那必須自己再retain, 釋放時再release。

(1)在iphone專案中,大家會看到乙個預設的autorelease pool,程式開始時建立,程式退出時銷毀,按照對autorelease的理解,豈不是所有autorelease pool裡的物件在程式退出時才release, 這樣跟記憶體洩露有什麼區別?

答案是,對於每乙個runloop, 系統會隱式建立乙個autorelease pool,這樣所有的release pool會構成乙個象callstack一樣的乙個棧式結構,在每乙個runloop結束時,當前棧頂的autorelease pool會被銷毀,這樣這個pool裡的每個object會被release。

那什麼是乙個runloop呢? 乙個ui事件,timer call, delegate call, 都會是乙個新的runloop。例子如下:

nsstring* globalobject;   

-(ibaction)onbuttonclicked  

iOS 學習筆記 RunLoop基礎

如果沒有runloop int main int argc,char argv int main int argc,char argv while running return 0 cf的記憶體管理 core foundation 1.凡是帶有create copy retain等字眼的函式,建立出...

IOS 多執行緒 RUNLOOP 機制 二

二,何時使用run loop 對於輔助線程,在需要和執行緒有更多互動時,才使用run loop。比如 1 使用埠或者自定義輸入源來和其他執行緒通訊 2 使用執行緒定時器 3 cocoa中使用任何performselector.的方法 參考 table performing selectors on ...

iOS開發 RunLoop的退出方式

通過 nsrunloop currentrunloop 或者cfrunloopgetcurrent 可以獲取當前執行緒的runloop。啟動乙個runloop有以下三種方法 void run void rununtildate nsdate limitdate void runmode nsstri...