定時(shí)器的深度用法

簡述:一個(gè)在確定時(shí)間間隔內(nèi)執(zhí)行一次或者多次我們指定對(duì)象方法的對(duì)象荒给。
如果是多次執(zhí)行對(duì)象方法萤捆,那么它怎么保證執(zhí)行的時(shí)候?qū)ο蟛槐会尫拍兀?/p>

問題:
1.你知道NSTimer會(huì)retain你添加調(diào)用方法的對(duì)象嗎吝镣?
2.你知道NSTimer并不是每次都準(zhǔn)確按你設(shè)定的時(shí)間間隔來觸發(fā)嗎徙瓶?
3.NSTimer需要和NSRunLoop結(jié)合起來使用击费,你知道是怎么結(jié)合使用的嗎至扰?
4.你知道除了用NSTimer實(shí)現(xiàn)定時(shí)器,還有別的方式也能實(shí)現(xiàn)定時(shí)器嗎茬暇?

大綱:
1.定時(shí)器的應(yīng)用場(chǎng)景
2.定時(shí)器的常用方式
3.fire方法的正確理解
4.NSRunLoopMode對(duì)定時(shí)器的影響
5.定時(shí)器一定會(huì)在規(guī)定時(shí)間間隔內(nèi)實(shí)時(shí)出發(fā)事件嗎首昔?
6.定時(shí)器引起的循環(huán)引用
7.子線程開啟定時(shí)器
8.GCD定時(shí)器

一:定時(shí)器的使用

第一種:

_timer = [NSTimer timerWithTimeInterval:1.f target:self selector:@selector(timerAction) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSDefaultRunLoopMode];//需要手動(dòng)把定時(shí)器加入到RunLoop里面才會(huì)生效

第二種:

_timer = [NSTimer scheduledTimerWithTimeInterval:1.f target:self selector:@selector(timerAction) userInfo:nil repeats:YES]; //系統(tǒng)會(huì)自動(dòng)加到RunLoop里面

注:iOS10之后增加了block方式的定時(shí)器初始化,為了避免之前方式所引起的循環(huán)引用問題:timer和scheduled都有:

(這樣就會(huì)消除循環(huán)引用糙俗,正常調(diào)用dealloc方法了)

__weak typeof(self) weakSelf = self;
_timer = [NSTimer scheduledTimerWithTimeInterval:1 repeats:YES block:^(NSTimer * _Nonnull timer) {
// NSLog(@"blockAction");
[weakSelf timerAction];
}];

實(shí)時(shí)觸發(fā)定時(shí)器勒奇,調(diào)用定時(shí)器方法,而且不會(huì)影響timer的響應(yīng)周期
[_timer fire];

定時(shí)器銷毀的唯一方法:
[_timer invalidate];

注意點(diǎn)1:子線程上的定時(shí)器巧骚,請(qǐng)?jiān)谧泳€程銷毀

[NSThread detachNewThreadSelector:@selector(ThreadTimer) toTarget:self withObject:nil];

  • (void)ThreadTimer {
    _timer = [NSTimer scheduledTimerWithTimeInterval:1.f target:self selector:@selector(timerAction) userInfo:nil repeats:YES];

    //子線程上的定時(shí)器赊颠,必須要在子線程里面invalidate格二,否則會(huì)造成資源的浪費(fèi)

    [self performSelector:@selector(invalidateTimer) withObject:nil afterDelay:3.f];

    //RunLoop在子線程上,是需要你手動(dòng)開啟竣蹦,RunLoop
    //RunLoop 的創(chuàng)建 [NSRunLoop currentRunLoop],當(dāng)獲取當(dāng)前RunLoop的時(shí)候顶猜,系統(tǒng)就已經(jīng)自動(dòng)創(chuàng)建好了,并不是alloc
    [[NSRunLoop currentRunLoop] run];
    NSLog(@"我在學(xué)習(xí)中");//當(dāng)RunLoop結(jié)束 才會(huì)執(zhí)行下面的語句
    }
    注意點(diǎn)2:注意定時(shí)器的線程里痘括,不要做復(fù)雜的計(jì)算操作长窄,這樣會(huì)導(dǎo)致定時(shí)器不準(zhǔn)確

GCD定時(shí)器:

//內(nèi)存問題:當(dāng)timeTwo(且eventhandle里沒有包含timer) 為成員變量的時(shí)候 沒問題;當(dāng)為局部變量的時(shí)候纲菌,只運(yùn)行一次

__weak typeof(self) weakSelf = self;
dispatch_queue_t queue = dispatch_queue_create("gcd實(shí)現(xiàn)定時(shí)器", 0);
 timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 1.f * NSEC_PER_SEC, 0 * NSEC_PER_SEC);
dispatch_source_set_event_handler(timer, ^{

// timer;//引用計(jì)數(shù)挠日,不會(huì)被釋放
// if (!repeats) {
// dispatch_cancel(timer);
// }else{
[weakSelf timerAction];
// }
});
dispatch_resume(timer);

gcd定時(shí)器的銷毀:dispatch_cancel(timer);

Display定時(shí)器:

創(chuàng)建:

displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(timerAction)];
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

停止:
[displayLink invalidate];
①屏幕刷新時(shí)調(diào)用
CADisplayLink是一個(gè)能讓我們以和屏幕刷新率同步的頻率將特定的內(nèi)容畫到屏幕上的定時(shí)器類。CADisplayLink以特定模式注冊(cè)到runloop后翰舌,每當(dāng)屏幕顯示內(nèi)容刷新結(jié)束的時(shí)候嚣潜,runloop就會(huì)向CADisplayLink指定的target發(fā)送一次指定的selector消息, CADisplayLink類對(duì)應(yīng)的selector就會(huì)被調(diào)用一次椅贱。所以通常情況下懂算,按照iOS設(shè)備屏幕的刷新率60次/秒
②延遲
iOS設(shè)備的屏幕刷新頻率是固定的,CADisplayLink在正常情況下會(huì)在每次刷新結(jié)束都被調(diào)用夜涕,精確度相當(dāng)高犯犁。但如果調(diào)用的方法比較耗時(shí),超過了屏幕刷新周期女器,就會(huì)導(dǎo)致跳過若干次回調(diào)調(diào)用機(jī)會(huì)酸役。
如果CPU過于繁忙,無法保證屏幕60次/秒的刷新率驾胆,就會(huì)導(dǎo)致跳過若干次調(diào)用回調(diào)方法的機(jī)會(huì)涣澡,跳過次數(shù)取決CPU的忙碌程度。
③使用場(chǎng)景
從原理上可以看出丧诺,CADisplayLink適合做界面的不停重繪入桂,比如視頻播放的時(shí)候需要不停地獲取下一幀用于界面渲染。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末驳阎,一起剝皮案震驚了整個(gè)濱河市抗愁,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌呵晚,老刑警劉巖蜘腌,帶你破解...
    沈念sama閱讀 212,454評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異饵隙,居然都是意外死亡撮珠,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門金矛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來芯急,“玉大人勺届,你說我怎么就攤上這事∪⑺#” “怎么了免姿?”我有些...
    開封第一講書人閱讀 157,921評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長伺绽。 經(jīng)常有香客問我养泡,道長嗜湃,這世上最難降的妖魔是什么奈应? 我笑而不...
    開封第一講書人閱讀 56,648評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮购披,結(jié)果婚禮上杖挣,老公的妹妹穿的比我還像新娘。我一直安慰自己刚陡,他們只是感情好惩妇,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著筐乳,像睡著了一般歌殃。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蝙云,一...
    開封第一講書人閱讀 49,950評(píng)論 1 291
  • 那天氓皱,我揣著相機(jī)與錄音,去河邊找鬼勃刨。 笑死波材,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的身隐。 我是一名探鬼主播廷区,決...
    沈念sama閱讀 39,090評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼贾铝!你這毒婦竟也來了隙轻?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,817評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤垢揩,失蹤者是張志新(化名)和其女友劉穎玖绿,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體水孩,經(jīng)...
    沈念sama閱讀 44,275評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡镰矿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了俘种。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片秤标。...
    茶點(diǎn)故事閱讀 38,724評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡绝淡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出苍姜,到底是詐尸還是另有隱情牢酵,我是刑警寧澤,帶...
    沈念sama閱讀 34,409評(píng)論 4 333
  • 正文 年R本政府宣布衙猪,位于F島的核電站馍乙,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏垫释。R本人自食惡果不足惜丝格,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評(píng)論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望棵譬。 院中可真熱鬧显蝌,春花似錦、人聲如沸订咸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽脏嚷。三九已至骆撇,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間父叙,已是汗流浹背神郊。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評(píng)論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留高每,地道東北人屿岂。 一個(gè)月前我還...
    沈念sama閱讀 46,503評(píng)論 2 361
  • 正文 我出身青樓,卻偏偏與公主長得像鲸匿,于是被迫代替她去往敵國和親爷怀。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評(píng)論 2 350

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