理解run loop後,才能徹底理解nstimer的實現原理,也就是說nstimer實際上依賴run loop實現的。
先看看nstimer的兩個常用方法:
+ (nstimer *)timerwithtimeinterval:(nstimeinterval)ti target:(id)atarget selector:(sel)aselector userinfo:(id)userinfo repeats:(bool)yesorno;//生成timer但不執行
+ (nstimer *)scheduledtimerwithtimeinterval:(nstimeinterval)ti target:(id)atarget selector:(sel)aselector userinfo:(id)userinfo repeats:(bool)yesorno;//生成timer並且納入當前執行緒的run loop來執行
nsrunloop與timer有關方法為:
- (void)addtimer:(nstimer *)timer formode:(nsstring *)mode;//在run loop上註冊timer
主線程已經有run loop,所以nstimer一般在主線程上執行都不必再呼叫addtimer:。但在非主線程上執行必須配置run loop,該執行緒的main方法示例**如下:
- (void)main
[runloop rununtildate:[nsdate datewithtimeintervalsincenow:10.0]];//每隔10秒檢查下執行緒迴圈條件,當然時間值可以根據實際情況來定。
我們通常在主線程中使用nstimer,有個實際遇到的問題需要注意。當滑動介面時,系統為了更好地處理ui事件和滾動顯示,主線程runloop會暫時停止處理一些其它事件,這時主線程中執行的nstimer就會被暫停。解決辦法就是改變nstimer執行的mode(mode可以看成事件型別),不使用預設的nsdefaultrunloopmode,而是改用nsrunloopcommonmodes,這樣主線程就會繼續處理nstimer事件了。具體**如下:
nstimer *timer =
[nstimer timerwithtimeinterval:
1.0 target:
self selector:
@selector
(timer:) userinfo:
nil repeats:
yes];
[[
nsrunloop currentrunloop] addtimer:t
imer formode:
nsrunloopcommonmodes
];
大家可以參看博文加深理解nstimer和nsrunloop的關係。
以前博文中提到延遲呼叫的方法,其實就是在當前執行緒的run loop上註冊timer來實現定時執行的。所以如果是在非主線程上使用,一定要有乙個run loop。
- (void)performselector:(sel)aselector withobject:(id)anargument afterdelay:(nstimeinterval)delay inmodes:(nsarray *)modes;
- (void)performselector:(sel)aselector withobject:(id)anargument afterdelay:(nstimeinterval)delay;
iOS多執行緒的初步研究(四) NSTimer
先看看nstimer的兩個常用方法 nstimer timerwithtimeinterval nstimeinterval ti target id atarget selector sel aselector userinfo id userinfo repeats bool yesorno 生...
iOS多執行緒的初步研究(四) NSTimer
理解run loop後,才能徹底理解nstimer的實現原理,也就是說nstimer實際上依賴run loop實現的。先看看nstimer的兩個常用方法 nstimer timerwithtimeinterval nstimeinterval ti target id atarget selecto...
iOS多執行緒的初步研究(四) NSTimer
先看看nstimer的兩個常用方法 nstimer timerwithtimeinterval nstimeinterval ti target id atarget selector sel aselector userinfo id userinfo repeats bool yesorno 生...