iOS三種定時器的用法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對象的計數(shù)器會加1尤溜,直到執(zhí)行完畢倔叼,自動減1。如果是循環(huán)執(zhí)行的話宫莱,就必須手動關閉丈攒,否則可以不執(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的實際觸發(fā)事件的時間梢睛,都會與所加入的RunLoop和RunLoop Mode有關肥印,如果此RunLoop正在執(zhí)行一個連續(xù)性的運算,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后藏畅, 每當屏幕顯示內(nèi)容刷新結(jié)束的時候,runloop就會向 CADisplayLink指定的target發(fā)送一次指定的selector消息, CADisplayLink類對應的selector就會被調(diào)用一次愉阎。

iOS設備的屏幕刷新頻率是固定的绞蹦,CADisplayLink在正常情況下會在每次刷新結(jié)束都被調(diào)用,精確度相當高榜旦。使用場合相對專一幽七,適合做UI的不停重繪,比如自定義動畫引擎或者視頻播放的渲染溅呢。不需要在格外關心屏幕的刷新頻率了澡屡,本身就是跟屏幕刷新同步的。

三咐旧,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.重復執(zhí)行

NSTimeInterval period = 1.0; //設置時間間隔    

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的定時器不受影響坤溃,因為RunLoop也是基于GCD的


計時器(全局)

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

@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];
}

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

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

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

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

- (void)stopTimer {
    if (_timer) {
        [_timer invalidate];
    }
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末劈狐,一起剝皮案震驚了整個濱河市勤哗,隨后出現(xiàn)的幾起案子彼念,更是在濱河造成了極大的恐慌屡律,老刑警劉巖腌逢,帶你破解...
    沈念sama閱讀 216,843評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異疹尾,居然都是意外死亡上忍,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,538評論 3 392
  • 文/潘曉璐 我一進店門纳本,熙熙樓的掌柜王于貴愁眉苦臉地迎上來窍蓝,“玉大人,你說我怎么就攤上這事繁成∠朋希” “怎么了?”我有些...
    開封第一講書人閱讀 163,187評論 0 353
  • 文/不壞的土叔 我叫張陵巾腕,是天一觀的道長面睛。 經(jīng)常有香客問我,道長尊搬,這世上最難降的妖魔是什么叁鉴? 我笑而不...
    開封第一講書人閱讀 58,264評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮佛寿,結(jié)果婚禮上幌墓,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好常侣,可當我...
    茶點故事閱讀 67,289評論 6 390
  • 文/花漫 我一把揭開白布蜡饵。 她就那樣靜靜地躺著,像睡著了一般胳施。 火紅的嫁衣襯著肌膚如雪溯祸。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,231評論 1 299
  • 那天舞肆,我揣著相機與錄音焦辅,去河邊找鬼。 笑死胆绊,一個胖子當著我的面吹牛氨鹏,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播压状,決...
    沈念sama閱讀 40,116評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼仆抵,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了种冬?” 一聲冷哼從身側(cè)響起镣丑,我...
    開封第一講書人閱讀 38,945評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎娱两,沒想到半個月后莺匠,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,367評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡十兢,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,581評論 2 333
  • 正文 我和宋清朗相戀三年趣竣,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片旱物。...
    茶點故事閱讀 39,754評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡遥缕,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出宵呛,到底是詐尸還是另有隱情单匣,我是刑警寧澤,帶...
    沈念sama閱讀 35,458評論 5 344
  • 正文 年R本政府宣布宝穗,位于F島的核電站户秤,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏逮矛。R本人自食惡果不足惜鸡号,卻給世界環(huán)境...
    茶點故事閱讀 41,068評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望须鼎。 院中可真熱鬧膜蠢,春花似錦堪藐、人聲如沸莉兰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,692評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽糖荒。三九已至杉辙,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間捶朵,已是汗流浹背蜘矢。 一陣腳步聲響...
    開封第一講書人閱讀 32,842評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留综看,地道東北人品腹。 一個月前我還...
    沈念sama閱讀 47,797評論 2 369
  • 正文 我出身青樓,卻偏偏與公主長得像红碑,于是被迫代替她去往敵國和親舞吭。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,654評論 2 354

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