我們把環境都設定在cocoa中,這裡所講的timer就用nstimer,當然這裡的原理適用於其他系統的timer。
因為nstimer是作為一種timer
resource加入到nsrunloop中去,在當timer的時間累計到規定時間之後就觸發timer的action。從這個過程上看來timer應該是很「準時」的,而且現實情況也是這樣的,比如乙個規定每1s觸發的timer絕大多數情況一般也是1s觸發一次。但是timer的這種所謂的「準時」千萬不要讓你產生這樣一種幻覺,「timer可以用來作精確的迴圈控制,比如用來精準控制動畫」。
timer的不精確性主要是表現在:timer有可能delay或者丟失。具體有下面幾種情形:
runloop沒有run或者run的model timer不支援。加入timer加入的是defaule
mode,但是這個時候使用者在如nsrunloop概述和原理中第一段**中,用的是某個使用者自己定於的mode在run這個runloop那麼timer的計時就沒有被累加。之有當runloop的model支援該timer的時候,該timer計時才會累計。
所以timer只是一種非實時控制的,「粗略」地計時的一種工具,在通常我們對實時不太要求的時候timer滿足我們的需求,但是如果對實時要求很高,比如遊戲中,就得採取一些真正實時的手段來實現了。這裡我想起了很早的時候看過的乙份有戲**,其中的動畫效果都是由nstimer來控制的,當時我就石化了,雖然遊戲各種動畫都還能看,但是明顯不是很流暢,而且時快時慢。
結合上面說的,又會過頭看看sdl中對timer的實現就實在是太簡陋了,不過這種簡單的timer系統有的時候反而能夠提供很好的實時性。
十二 12
1.什麼是nsrunloop?
我們會經常看到這樣的**:
- (ibaction)start:(id)sender
[progress sethidden:yes];
}
這段**很神奇的,因為他會「暫停」**執行,而且程式執行不會因為這裡有乙個while迴圈而受到影響。在[progress
sethidden:no]執行之後,整個函式想暫停了一樣停在迴圈裡面,等loadpageinbackground裡面的操作都完成了以後才讓[progress
sethidden:yes]執行。這樣做就顯得簡潔,
而且邏輯很清晰。如果你不這樣做,你就需要在loadpageinbackground裡面表示load完成的地方呼叫[progress
sethidden:yes],顯得**不緊湊而且容易出錯。
2. nsrunloop工作原理
接下來看一下nsrunloop具體的工作原理,首先是官方文件提供的說法,看圖:
通過所有的「訊息」都被新增到了nsrunloop中去,而在這裡這些訊息並分為「input source」和「timer source」
並在迴圈中檢查是不是有事件需要發生,如果需要那麼就呼叫相應的函式處理。為了更清晰的解釋,我們來對比vc++和ios訊息處理過程。
vc++中在一切初始化都完成之後程式就開始這樣乙個迴圈了(**是從戶sir mfc程式設計課程的slides中擷取):
int apientry winmain(hinstance
hinstance,hinstance
hprevinstance,lpstr
lpcmdline,int ncmdshow)
}}
…while(running) NSRunLoop概述和原理
1.什麼是nsrunloop?我們會經常看到這樣的 1 2 3 4 5 6 7 8 9 10 ibaction start id sender progress sethidden yes 2.nsrunloop工作原理 接下來看一下nsrunloop具體的工作原理,首先是官方文件提供的說法,看圖 ...
NSRunLoop概述和原理
1.什麼是nsrunloop?我們會經常看到這樣的 1 2 3 4 5 6 7 8 9 10 ibaction start id sender progress sethidden yes 2.nsrunloop工作原理 接下來看一下nsrunloop具體的工作原理,首先是官方文件提供的說法,看圖 ...
NSRunLoop 概述和原理
1.什麼是nsrunloop?我們會經常看到這樣的 ibaction start id sender progress sethidden yes 這段 很神奇的,因為他會 暫停 執行,而且程式執行不會因為這裡有乙個while迴圈而受到影響。在 progress sethidden no 執行之後,...