? ? ? ?OC 中,經(jīng)常用到計(jì)時(shí)器,但OC給出的NSTimer這個(gè)定時(shí)器制作的類在使用的時(shí)候有很多問(wèn)題。
? ? ? 首先,在使用NSTimer的過(guò)程中,我們必須注意一個(gè)內(nèi)存泄漏的問(wèn)題,也就是說(shuō),做到NSTimer要及時(shí)銷毀。e g.

當(dāng)用以上方法創(chuàng)建計(jì)時(shí)器的時(shí)候,我們通常時(shí)添加一個(gè)控制器上面,這樣就造成了當(dāng)我們的控制器在壓棧的時(shí)候,不會(huì)銷毀,而會(huì)繼續(xù)計(jì)時(shí)。當(dāng)然我們可以用如下方法解決:

但是這需要你對(duì)每一個(gè)定時(shí)器做特定的銷毀,不然就會(huì)內(nèi)存泄漏。為了一勞永逸,(程序猿的”病“)這我還一個(gè)解決方案:那就是創(chuàng)建一個(gè)計(jì)時(shí)器不直接加在所要使用的控制器上,而是在中間加一個(gè)緩沖層,即在中間加一個(gè)類A,把定時(shí)器加在類A上,外面利用這個(gè)類創(chuàng)建計(jì)時(shí)器,并對(duì)這個(gè)類A進(jìn)行弱運(yùn)用。這樣就不會(huì)出現(xiàn)計(jì)時(shí)器不能被釋放的情況了:

? ? ? 其次,在使用上面的方法在遇到把定時(shí)器添加到一個(gè)scrollView上的時(shí)候,我們發(fā)現(xiàn)在滑動(dòng)scrollView的時(shí)候,我們的定時(shí)器又不動(dòng)了。這時(shí),我還有解決方案:把它添加到次線程里面去并且把其模式設(shè)為NSRunLoopCommonModes。e g.

雖然以上的方法都能解決我們的問(wèn)題,但是作為程序猿都有一顆求更完美的心;因此,我去找到了NSTimer的底層構(gòu)成原理GCD:用CGD制作的計(jì)時(shí)器,我們不僅不用擔(dān)心其,銷毀問(wèn)題,也不會(huì)有在scrollView滑動(dòng)的時(shí)候出現(xiàn)計(jì)時(shí)器停止的問(wèn)題。在利用GCD的時(shí)候,我發(fā)現(xiàn)一篇文章是說(shuō)用到了這個(gè)方法:
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(<#delayInSeconds#> * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{});來(lái)制作了一個(gè)計(jì)時(shí)器,并且有暫停等功能(代碼見(jiàn)github地址:https://github.com/StrongX/XTimer)
但是,我覺(jué)得這個(gè)方法來(lái)用CGD的話,并沒(méi)有挖掘出其真正的強(qiáng)大之處,為此我也寫(xiě)了一個(gè)CGD的計(jì)時(shí)器:主要原理是用了dispatch_queue_t,dispatch_source_t,dispatch_source_set_timer,dispatch_source_set_event_handler幾個(gè)CGD的函數(shù)來(lái)創(chuàng)建和處理事件,也包含了暫停、繼續(xù)、銷毀和重新開(kāi)始功能。(代碼見(jiàn)github地址:https://github.com/jonkerit/HHTimer)
作為一個(gè)菜鳥(niǎo),寫(xiě)寫(xiě)菜鳥(niǎo)代碼,有不足之處望大神們不吝賜教;
參考文章: