亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > iOS > 正文

iOS之UITableView計時器的實現方式總結(NSTimer、DispatchSource、CADisplayLink)

2019-10-21 18:39:12
字體:
來源:轉載
供稿:網友

前言

最近工作比較忙,但是還是出來更新博客了。今天博客中所涉及的內容并不復雜,都是一些平時常見的一些問題,通過這篇博客算是對UITableView中使用定時器的幾種方式進行總結。本篇博客會給出在TableView中使用NSTimer或者DispatchSourcer中常見的五種方式。當然下方第一種方式是常規做法,不過也是UITableView中使用NSTimer的一個坑。其他三種方式是為了繞過這個坑的解決方案。

當然,本篇博客共涉及到了UITableView中使用定時器的四種實現方式,當然應該也還有其他實現方式,只不過目前我沒有涉及到。歡迎在評論區提供其他實現方式,我會及時的整合到目前的Demo中。

接下來我們先來總結一下本篇博客所涉及的四種方式:

  • 第一種就是直接在TableView的Cell上使用NSTimer,當然這種方式是有問題的,稍后會介紹。
  • 第二種是將NSTimer添加到當前線程所對應的RunLoop中的commonModes中。
  • 第三種是通過Dispatch中的TimerSource來實現定時器。
  • 第四種是開啟一個新的子線程,將NSTimer添加到這個子線程中的RunLoop中,并使用DefaultRunLoopModes來執行。
  • 第五種方式就是使用CADisplayLink來實現。

下方我們將會根據具體的示例來詳細的介紹以上這五種實現方式。

一、在Cell中直接使用NSTimer

首先我們按照常規做法,直接在UITableView的Cell上添加相應的NSTimer, 并使用scheduledTimer執行相應的代碼塊。這種方式沒有什么特殊的就是對Timer的直接使用。下方是我們本部分的Timer的使用代碼,當然是使用Swift來實現的,不過與OC的代碼差不多。代碼如下所示 :

iOS,UITableView,計時器,NSTimer,DispatchSource,CADisplayLink

上述代碼比較簡單,就是在Cell上添加了一個定時器,然后沒1秒更新一次時間,并在Cell的timeLabel上顯示,運行效果如下所示。從該運行效果中我們不難發現,當我們滑動TableView時,該定時器就停止了工作。具體原因就是當前線程的RunLoop在TableView滑動時將DefaultMode切換到了TrackingRunLoopMode。因為Timer默認是添加在RunLoop上的DefaultMode上的,當Mode切換后Timer就停止了運行。

但是當停止滑動后,Mode又切換了回來,所以Timer有可以正常工作了。

  iOS,UITableView,計時器,NSTimer,DispatchSource,CADisplayLink

為了進一步看一下Mode的切換,我們可以在相應的地方獲取當前線程的RunLoop并且打印對應的Mode。下方代碼就是在TableView所對應的VC上添加的,我們在viewDidLoad()、viewDidAppear()以及scrollViewDidScroll()這個代理方法中對當前線程所對應的RunLoop下的currentMode進行了打印,其代碼如下。

iOS,UITableView,計時器,NSTimer,DispatchSource,CADisplayLink

iOS,UITableView,計時器,NSTimer,DispatchSource,CADisplayLink

下方就是最終的運行結果。從輸出結果中我們不難看出,在viewDidLoad()方法中打印的Current Mode為UIInitializationRunLoopMode, 從該Mode的名字中我們不難發現,該Mode負責UI的初始化。在viewDidApperar()方法中,也就是UI顯示后,RunLoop的Mode切換成了kCFRunLoopDefaultMode。緊接著,我們去滑動TableView,然后在scrollViewDidScroll()代理方法中打印滑動時當前RunLoop所對應的Mode。從下方運行結果不難看出,當TableView滑動時,打印出的currentModel為UITrackingRunLoopMode。當停止滑動后,點擊Show Current Mode按鈕獲取當前Mode時,打印的有時RunLoopDefaultMode。具體如下所示:

iOS,UITableView,計時器,NSTimer,DispatchSource,CADisplayLink

二、將Timer添加到CommonMode中

上一部分的定時器是不能正常運行的,因為NSTimer對象默認添加到了當前RunLoop的DefaultMode中,而在切換成TrackingRunLoopMode時,定時器就停止了工作。解決該問題最直接方法是,將NSTimer在TrackingRunLoopMode中也添加一份。這樣的話無論是在DefaultMode還是TrackingRunLoopMode中,定時器都會正常的工作。

如果你對RunLoop比較熟悉的話,可以知道CommonModes就是DefaultMode和TrackingRunLoopMode的集合,所以我們只需要將NSTimer對象與當前線程所對應的RunLoop中的CommonModes關聯即可,具體代碼如下所示:

iOS,UITableView,計時器,NSTimer,DispatchSource,CADisplayLink

上述代碼與第一部分的代碼不同的地方在于我們將創建好的定時器添加到了當前RunLoop中的CommonModes中,這樣的話可以保證TableView在滑動時定時器也可以正常運行。上述代碼最終的運行效果如下所示。

  iOS,UITableView,計時器,NSTimer,DispatchSource,CADisplayLink

從該運行效果我們不難發現,當該TableView滾動式,其Cell上的定時器是可以正常工作的。但是當我們滑動右上角的這個TableView時,第一個的TableView中的定時器也是不能正常工作的,因為這些TableView都在主線程中工作,也就是說這些TableView所在的RunLoop是同一個。

三、將Timer添加到子線程的RunLoop下的DefaultMode中

接下來我們來看另一種解決方案,就是開啟一個新的子線程,然后將Timer添加到這個子線程所對應的RunLoop中。當然因為是子線程的RunLoop,在添加Timer時,我們可以將Timer添加到子線程中的RunLoop中的DefaultMode中。添加完畢后,手動運行該RunLoop。

因為是在子線程中添加的Timer, Timer肯定是在子線程中工作的,所以在更新UI時,我們需要在主線程中進行更新,具體代碼如下所示:

iOS,UITableView,計時器,NSTimer,DispatchSource,CADisplayLink

在上述代碼中我們可以看到我們使用全局的并行隊列來異步創建了一個Timer對象,然后將該對象添加進了該異步線程中的DefaultRunLoopMode中,然后運行該RunLoop。當然在子線程中更新UI還是需要在主線程中去操作的。下方就是上述代碼的運行效果。從該效果中我們不難看出,當滑動TableView時定時器是可以正常工作的。

  iOS,UITableView,計時器,NSTimer,DispatchSource,CADisplayLink

四、DispatchTimerSource

接下來我們就不使用NSTimer來實現定時器了。在之前的博客中聊GCD時其中用到了DispatchTimerSource來實現定時器。接下來我們就在TableView的Cell上添加DispatchTimerSource,然后看一下運行效果。當然下方代碼片段我們是在全局隊列中添加的DispatchTimerSource,在主線程中進行更新。當然我們也可以在mainQueue中添加DispatchTimerSource,這樣也是可以正常工作的。當然我們不建議在MainQueue中做,因為在編程時盡量的把一些和主線程關聯不太大的操作放到子線程中去做。代碼如下所示:

iOS,UITableView,計時器,NSTimer,DispatchSource,CADisplayLink

接下來我們來看一下上述的代碼的運行效果,從該效果中我們可以看出該定時器是可以正常工作的。

  iOS,UITableView,計時器,NSTimer,DispatchSource,CADisplayLink

五、CADisplayLink

接下來我們來使用CADisplayLink來實現定時器功能,在之前的博客中我們也使用過CADisplayLink,不過是用來計算FPS的。下方代碼片段中我們就使用CADisplayLink來實現的定時器。CADisplayLink可以添加到RunLoop中,RunLoop的每一次循環都會觸發CADisplayLink所關聯的方法。在屏幕不卡頓的情況下,每次循環的時間時1/60秒。

下方代碼,為了不讓屏幕的卡頓等引起的主線程所對應的RunLoop阻塞所造成的定時器不精確的問題。我們開啟了一個新的線程,并且將CADisplayLink對象添加到這個子線程的RunLoop中,然后在主線程中更新UI即可。具體代碼如下:

iOS,UITableView,計時器,NSTimer,DispatchSource,CADisplayLink

我們對上述代碼運行,下方是其對應的運行結果。從下方運行結果中我們不難看出,在TableView滾動時該定時器也是可以正常運行的。當然該方式實現的定時器的精度是比較高的。

  iOS,UITableView,計時器,NSTimer,DispatchSource,CADisplayLink

經過上述五大部分,我們羅列了定時器的幾種實現方式,通過對比我們不難發現其優劣性。上述定時器中DispatchSourceTime以及CADisplayLink的精度要比NSTimer的精度要高。從代碼實現中我們不難看出CADisplayLink的精度是比較高的。

本篇博客所涉及代碼的github分享地址為:https://github.com/lizelu/NSTimerWithRunLoop

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對VEVB武林網的支持。


注:相關教程知識閱讀請移步到IOS開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久久久久久91| 亚洲午夜性刺激影院| 亚洲欧美另类在线观看| 国产一区二区视频在线观看| 亚洲第一区在线| 狠狠操狠狠色综合网| 国产视频精品一区二区三区| 久久久久久久久久久av| 欧美激情久久久久久| 欧美日本啪啪无遮挡网站| 国产精品亚发布| 欧美在线影院在线视频| 国产亚洲美女久久| 国产精品va在线播放| 伊人伊人伊人久久| 中文字幕在线看视频国产欧美在线看完整| 欧美日韩不卡合集视频| 国产欧美婷婷中文| 国外成人在线视频| 亚洲性无码av在线| 国产98色在线| 北条麻妃一区二区三区中文字幕| 91久久久国产精品| 久久久天堂国产精品女人| 日韩专区在线观看| 亚洲成年人在线| 97视频网站入口| 亚洲欧美在线x视频| 国产精品影片在线观看| 国产精品久久久一区| 国产精品一区二区av影院萌芽| 午夜精品久久久久久99热| 久久久久女教师免费一区| 国产精品一香蕉国产线看观看| 欧美日韩福利视频| 51精品在线观看| 久久精品国产欧美亚洲人人爽| 日韩免费在线视频| 欧美日韩精品二区| 亚洲一区二区在线| 亚洲在线一区二区| 亚洲午夜精品视频| 精品无码久久久久久国产| 2019中文字幕在线观看| 日韩国产高清污视频在线观看| 久久成人人人人精品欧| 一区二区三区四区视频| 色综合视频一区中文字幕| 日本国产一区二区三区| 成人久久18免费网站图片| 亚洲欧美制服另类日韩| 97视频在线观看视频免费视频| 国产精品久久电影观看| 日韩欧美亚洲成人| 国产欧美一区二区三区四区| 成人免费大片黄在线播放| 亚洲精品视频免费在线观看| 成人午夜高潮视频| 国产精品日日做人人爱| 亚洲精品第一页| 亚洲a级在线播放观看| 最新日韩中文字幕| 欧美第一黄网免费网站| 亚洲欧美国产精品va在线观看| 亚洲欧美日本精品| 日韩在线视频国产| 日韩有码在线电影| 色妞欧美日韩在线| 亚洲精品wwww| 欧美另类99xxxxx| 国产精品精品视频| 亚洲精品福利视频| 亚洲欧美日韩天堂| 国产精品久久久久影院日本| 亚洲精品网址在线观看| 成人免费看片视频| 欧美日韩国产91| 日本不卡免费高清视频| 欧美日韩国产一区中文午夜| 亚洲国模精品一区| 日本精品久久久久影院| 国产一区二区黄| 2025国产精品视频| 欧美亚洲成人免费| 亚洲三级黄色在线观看| 日韩视频免费在线| 亚洲成人精品久久久| 日韩中文字幕在线视频| 欧美性xxxx18| 国产精品成人久久久久| 久久99视频免费| 欧美肥老妇视频| 日本亚洲精品在线观看| 欧美xxxx综合视频| 日韩电影大全免费观看2023年上| 精品国产乱码久久久久久天美| 日韩有码片在线观看| xxx欧美精品| 久久亚洲精品视频| 97视频在线观看视频免费视频| 亚洲精品乱码久久久久久金桔影视| 国产专区欧美专区| 日韩欧美亚洲综合| 久久久精品视频在线观看| 黑人极品videos精品欧美裸| 亚洲free嫩bbb| 中文国产成人精品久久一| 欧美小视频在线观看| 91a在线视频| 欧美激情精品久久久久久变态| 精品亚洲精品福利线在观看| 九九热r在线视频精品| 欧美一级淫片丝袜脚交| 久久综合伊人77777| 日韩精品中文字| 成人春色激情网| 欧美日韩视频免费播放| 欧美巨大黑人极品精男| 黑人与娇小精品av专区| 国产xxx69麻豆国语对白| 国产情人节一区| 亚洲精品日产aⅴ| 亚洲国产中文字幕在线观看| 久久精品国产亚洲精品2020| 国产精品嫩草影院久久久| 日韩av电影免费观看高清| 91视频国产精品| 久久久精品一区二区| 亚洲石原莉奈一区二区在线观看| 97精品国产97久久久久久春色| 菠萝蜜影院一区二区免费| 91最新在线免费观看| 97人洗澡人人免费公开视频碰碰碰| 91系列在线播放| 久久久久久久一区二区| 精品视频久久久久久久| 国产成人精品国内自产拍免费看| 久久夜精品va视频免费观看| 91精品久久久久久久久久另类| 国产精品久久久久久av| 亚洲国产私拍精品国模在线观看| 亚洲第一av网站| 91精品视频一区| 亚洲成av人影院在线观看| 97人洗澡人人免费公开视频碰碰碰| 亚洲成人av在线| 另类美女黄大片| 欧美裸体视频网站| 国产91精品黑色丝袜高跟鞋| 久久久久国产一区二区三区| 亚洲天堂免费观看| 久久这里只有精品99| 久久成人一区二区| 国产精品久久久久久av下载红粉| 最新国产精品亚洲| 这里只有精品久久| 欧美精品日韩三级| 色综合视频一区中文字幕| 78m国产成人精品视频| 国产精品视频精品视频| 91亚洲国产成人久久精品网站| 在线中文字幕日韩| 亚洲日韩中文字幕| 北条麻妃99精品青青久久|