一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - IOS - iOS之UITableView計時器的實現方式總結(NSTimer、DispatchSource、CADisplayLink)

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

2021-05-18 20:12青玉伏案 IOS

這篇文章主要給大家介紹了關于iOS之UITableView計時器的實現方式,其中包括NSTimer、DispatchSource、CADisplayLink等方法,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下

前言

最近工作比較忙,但是還是出來更新博客了。今天博客中所涉及的內容并不復雜,都是一些平時常見的一些問題,通過這篇博客算是對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

總結

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

原文鏈接:https://www.cnblogs.com/ludashi/p/7349535.html

延伸 · 閱讀

精彩推薦
  • IOSiOS自定義UICollectionViewFlowLayout實現圖片瀏覽效果

    iOS自定義UICollectionViewFlowLayout實現圖片瀏覽效果

    這篇文章主要介紹了iOS自定義UICollectionViewFlowLayout實現圖片瀏覽效果的相關資料,需要的朋友可以參考下...

    jiangamh8882021-01-11
  • IOSiOS中MD5加密算法的介紹和使用

    iOS中MD5加密算法的介紹和使用

    MD5加密是最常用的加密方法之一,是從一段字符串中通過相應特征生成一段32位的數字字母混合碼。對輸入信息生成唯一的128位散列值(32個字符)。這篇文...

    LYSNote5432021-02-04
  • IOSiOS實現控制屏幕常亮不變暗的方法示例

    iOS實現控制屏幕常亮不變暗的方法示例

    最近在工作中遇到了要將iOS屏幕保持常亮的需求,所以下面這篇文章主要給大家介紹了關于利用iOS如何實現控制屏幕常亮不變暗的方法,文中給出了詳細的...

    隨風13332021-04-02
  • IOSiOS開發技巧之狀態欄字體顏色的設置方法

    iOS開發技巧之狀態欄字體顏色的設置方法

    有時候我們需要根據不同的背景修改狀態欄字體的顏色,下面這篇文章主要給大家介紹了關于iOS開發技巧之狀態欄字體顏色的設置方法,文中通過示例代碼...

    夢想家-mxj8922021-05-10
  • IOSiOS開發之視圖切換

    iOS開發之視圖切換

    在iOS開發中視圖的切換是很頻繁的,獨立的視圖應用在實際開發過程中并不常見,除非你的應用足夠簡單。在iOS開發中常用的視圖切換有三種,今天我們將...

    執著丶執念5282021-01-16
  • IOSiOS中滑動控制屏幕亮度和系統音量(附加AVAudioPlayer基本用法和Masonry簡單使用)

    iOS中滑動控制屏幕亮度和系統音量(附加AVAudioPlayer基本用法和

    這篇文章主要介紹了iOS中滑動控制屏幕亮度和系統音量(附加AVAudioPlayer基本用法和Masonry簡單使用)的相關資料,需要的朋友可以參考下...

    CodingFire13652021-02-26
  • IOSiOS中UILabel實現長按復制功能實例代碼

    iOS中UILabel實現長按復制功能實例代碼

    在iOS開發過程中,有時候會用到UILabel展示的內容,那么就設計到點擊UILabel復制它上面展示的內容的功能,也就是Label長按復制功能,下面這篇文章主要給大...

    devilx12792021-04-02
  • IOS詳解iOS中多個網絡請求的同步問題總結

    詳解iOS中多個網絡請求的同步問題總結

    這篇文章主要介紹了詳解iOS中多個網絡請求的同步問題總結,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧...

    liang199111312021-03-15
主站蜘蛛池模板: 欧美性理论片在线观看片免费 | 亚洲精品一区波多野结衣 | 精品亚洲永久免费精品 | 午夜勾魂曲 | 疯狂伦交1一6 小说 风间由美在线 | 波多野给衣一区二区三区 | 欧洲美女啪啪 | 菠萝视频污 | 9久久9久久精品 | 色吧欧美| 黑白配高清hd在线视频 | 攻插受| 亚洲免费色图 | 国产日韩欧美综合在线 | 欧美精品一区二区在线观看 | 日韩一级精品视频在线观看 | 国内精品视频一区二区三区八戒 | 日本制服丝袜 | 久久爽狠狠添AV激情五月 | 美女翘臀内疯狂进出 | 亚洲精品一区二区久久这里 | 日本在线看| 日韩亚洲人成网站在线播放 | 免费高清特黄a 大片 | 日本黄大片影院一区二区 | 亚洲成人网在线 | 欧美视频一区二区三区四区 | 久久88综合 | 国产精品网页 | 暖暖视频日本 | 青青青国产在线 | 暖暖在线精品日本中文 | 九色PORNY蝌蚪视频首页 | 亚洲美色综合天天久久综合精品 | 极品虎白女在线观看一线天 | 日韩精品一区二区三区视频 | 久久成人免费大片 | 欧美一卡2卡三卡4卡5卡免费观看 | 日韩精品视频在线播放 | 5x社区在线观看直接进入 | 成人福利网站含羞草 |