iOS開發(fā)--三種定時器的用法NSTimer顶岸、CADisplayLink腔彰、GCD


一,NSTimer

//創(chuàng)建方式1
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(action:) userInfo:nil repeats:NO];
[timer invalidate];
 //調(diào)用創(chuàng)建方法后蜕琴,target對象的計(jì)數(shù)器會加1萍桌,直到執(zhí)行完畢,自動減1凌简。如果是循環(huán)執(zhí)行的話上炎,就必須手動關(guān)閉,否則可以不執(zhí)行釋放方法雏搂。

//推薦-->創(chuàng)建方式2
NSTimer *timer = [NSTimer timerWithTimeInterval:5 target:self selector:@selector(timerAction) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:timer   forMode:NSDefaultRunLoopMode];
[timer invalidate];

說明:存在延遲藕施,不管是一次性的還是周期性的timer的實(shí)際觸發(fā)事件的時間,都會與所加入的RunLoop和RunLoop Mode有關(guān)凸郑,如果此RunLoop正在執(zhí)行一個連續(xù)性的運(yùn)算裳食,timer就會被延時出發(fā)。

二芙沥,CADisplayLink
- (void)startDisplayLink{
self.displayLink = [CADisplayLink displayLinkWithTarget:self
selector:@selector(handleDisplayLink:)];
[self.displayLink addToRunLoop:[NSRunLoop currentRunLoop]
forMode:NSDefaultRunLoopMode];
}

- (void)handleDisplayLink:(CADisplayLink *)displayLink{
//do something
}

  - (void)stopDisplayLink{
[self.displayLink invalidate];
self.displayLink = nil;
}

說明:CADisplayLink是一個能讓我們以和屏幕刷新率同步的頻率將特 定的內(nèi)容畫到屏幕上的定時器類诲祸。 CADisplayLink以特定模式注冊到runloop后浊吏, 每當(dāng)屏幕顯示內(nèi)容刷新結(jié)束的時候,runloop就會向 CADisplayLink指定的target發(fā)送一次指定的selector消息救氯, CADisplayLink類對應(yīng)的selector就會被調(diào)用一次找田。

iOS設(shè)備的屏幕刷新頻率是固定的,CADisplayLink在正常情況下會在每次刷新結(jié)束都被調(diào)用着憨,精確度相當(dāng)高墩衙。使用場合相對專一,適合做UI的不停重繪甲抖,比如自定義動畫引擎或者視頻播放的渲染漆改。不需要在格外關(guān)心屏幕的刷新頻率了,本身就是跟屏幕刷新同步的准谚。

三挫剑,GCD
1.執(zhí)行一次

double delayInSeconds = 2.0;    

dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);   

 dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ 
      //執(zhí)行事件    
});

2.重復(fù)執(zhí)行

NSTimeInterval period = 1.0; //設(shè)置時間間隔    

 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);    dispatch_source_t _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);    dispatch_source_set_timer(_timer, dispatch_walltime(NULL, 0), period * NSEC_PER_SEC, 0); //每秒執(zhí)行    

dispatch_source_set_event_handler(_timer, ^{    //在這里執(zhí)行事件    });

dispatch_resume(_timer);
 GCD的定時器和NSTimer是不一樣的,NSTimer受RunLoop影響柱衔,但是GCD的定時器不受影響暮顺,因?yàn)镽unLoop也是基于GCD的

計(jì)時器(全局)
 @interface ViewController ()
 @property(nonatomic,strong)NSTimer *timer; // timer
@property(nonatomic,assign)int countDown; // 倒數(shù)計(jì)時用
@property(nonatomic,strong)NSDate *beforeDate; // 上次進(jìn)入后臺時間

@end

static int const tick = 60;

@implementation ViewController

- (void)viewDidLoad {
[super viewDidLoad];
[self setupNotification];
[self startCountDown];
}

-(void)dealloc {
[[NSNotificationCenter defaultCenter]removeObserver:self name:UIApplicationDidEnterBackgroundNotification object:nil];
[[NSNotificationCenter defaultCenter]removeObserver:self name:UIApplicationWillEnterForegroundNotification object:nil];
[self stopTimer];
}

-(void)setupNotification {
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(enterBG) name:UIApplicationDidEnterBackgroundNotification object:nil];
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(enterFG) name:UIApplicationWillEnterForegroundNotification object:nil];
}

/**
   *  進(jìn)入后臺記錄當(dāng)前時間
 */
-(void)enterBG {
NSLog(@"應(yīng)用進(jìn)入后臺啦");
_beforeDate = [NSDate date];
}

/**
 *  返回前臺時更新倒計(jì)時值
   */
-(void)enterFG {
NSLog(@"應(yīng)用將要進(jìn)入到前臺");
NSDate * now = [NSDate date];
int interval = (int)ceil([now timeIntervalSinceDate:_beforeDate]);
int val = _countDown - interval;
if(val > 1){
    _countDown -= interval;
}else{
    _countDown = 1;
}
}

/**
 *  開始倒計(jì)時
   */
-(void)startCountDown {
_countDown = tick; //< 重置計(jì)時
_timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(timerFired:) userInfo:nil repeats:YES]; //< 需要加入手動RunLoop,需要注意的是在NSTimer工作期間self是被強(qiáng)引用的
[[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes]; //< 使用NSRunLoopCommonModes才能保證RunLoop切換模式時秀存,NSTimer能正常工作捶码。
}

-(void)timerFired:(NSTimer *)timer {
if (_countDown == 0) {
    [self stopTimer];
    NSLog(@"重新發(fā)送");
}else{
    _countDown -=1;
    NSLog(@"倒計(jì)時中:%d",_countDown);
}
}

- (void)stopTimer {
if (_timer) {
    [_timer invalidate];
}
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市或链,隨后出現(xiàn)的幾起案子惫恼,更是在濱河造成了極大的恐慌,老刑警劉巖澳盐,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件祈纯,死亡現(xiàn)場離奇詭異,居然都是意外死亡叼耙,警方通過查閱死者的電腦和手機(jī)腕窥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來筛婉,“玉大人簇爆,你說我怎么就攤上這事∷觯” “怎么了入蛆?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長硕勿。 經(jīng)常有香客問我哨毁,道長,這世上最難降的妖魔是什么源武? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任扼褪,我火速辦了婚禮想幻,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘话浇。我一直安慰自己举畸,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布凳枝。 她就那樣靜靜地躺著,像睡著了一般跋核。 火紅的嫁衣襯著肌膚如雪岖瑰。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天砂代,我揣著相機(jī)與錄音蹋订,去河邊找鬼。 笑死刻伊,一個胖子當(dāng)著我的面吹牛露戒,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播捶箱,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼智什,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了丁屎?” 一聲冷哼從身側(cè)響起荠锭,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎晨川,沒想到半個月后证九,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡共虑,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年愧怜,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片妈拌。...
    茶點(diǎn)故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡拥坛,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出尘分,到底是詐尸還是另有隱情渴逻,我是刑警寧澤,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布音诫,位于F島的核電站惨奕,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏竭钝。R本人自食惡果不足惜梨撞,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一雹洗、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧卧波,春花似錦时肿、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至查坪,卻和暖如春寸宏,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背偿曙。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工氮凝, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人望忆。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓罩阵,卻偏偏與公主長得像,于是被迫代替她去往敵國和親启摄。 傳聞我的和親對象是個殘疾皇子稿壁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內(nèi)容