最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

iOS DispatchSourceTimer 定時器的具體使用

 更新時間:2022年05月07日 11:31:13   作者:大番薯醬  
定時器在很多地方都可以用到,本文主要介紹了iOS DispatchSourceTimer 定時器的具體使用,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下

1. 概述

說起計時器,很多開發(fā)人員第一時間就會想起Timer,但是隨著使用的深入,慢慢就發(fā)現(xiàn)Timer其實不是很好用,比如說TableView滑動時候不執(zhí)行,Timer循環(huán)應(yīng)用。

2. DispatchSourceTimer

DispatchSourceTimer,也就是大家通常叫的GCD Timer,是依賴于GCD的一種Timer,Runloop的底層代碼中也用到這種Timer,可見GCD Timer并不依賴與Runloop。

先看一下蘋果的定義:

A dispatch source that submits the event handler block based on a timer.

2.1 GCD Timer 創(chuàng)建

使用下面的方法即可創(chuàng)建一個DispatchSourceTimer對象。

class func makeTimerSource(flags: DispatchSource.TimerFlags = [], queue: DispatchQueue? = nil) -> DispatchSourceTimer
// 默認(rèn)在主隊列中調(diào)度使用
let timer = DispatchSource.makeTimerSource()
// 指定在主隊列中調(diào)度使用
let timer = DispatchSource.makeTimerSource(flags: [], queue: DispatchQueue.main)
// 指定在全局隊列中調(diào)度使用
let timer = DispatchSource.makeTimerSource(flags: [], queue: DispatchQueue.global())
// 指定在自定義隊列中調(diào)度使用
let customQueue = DispatchQueue(label: "customQueue")
let timer = DispatchSource.makeTimerSource(flags: [], queue: customQueue)

2.2 GCD Timer 配置

配置Timer參數(shù),需要使用DispatchSourceTimer協(xié)議的方法??梢园才乓淮位蚨啻斡|發(fā)的Timer。Timer每次觸發(fā)的時候,都會調(diào)用已部署的任務(wù)。

    // 從現(xiàn)在開始,每秒執(zhí)行一次。
    timer?.schedule(deadline: DispatchTime.now(), repeating: .seconds(1), leeway: .nanoseconds(1))
    // 5秒之后執(zhí)行任務(wù),不重復(fù)。
    timer?.schedule(deadline: DispatchTime.now() + 5, repeating: .never, leeway: .nanoseconds(1))

2.3 GCD Timer 部署任務(wù)

當(dāng)Timer配置完參數(shù)后,使用DispatchSourceProtocol協(xié)議的方法來部署要執(zhí)行的任務(wù)。

setEventHandler和setRegistrationHandler的區(qū)別:

  • setEventHandler:給Timer設(shè)置要執(zhí)行的任務(wù),包括一次性任務(wù)和定時重復(fù)的任務(wù)?;卣{(diào)方法在子線程中執(zhí)行。
  • setRegistrationHandler:這個方法設(shè)置的任務(wù)只會執(zhí)行一次,也就是在Timer就緒后開始運行的時候執(zhí)行,類似于Timer開始的一個通知回調(diào)?;卣{(diào)方法在子線程中執(zhí)行。

例如下面的代碼:

var timer: DispatchSourceTimer?

func initTimer() {
    // 默認(rèn)在主隊列中調(diào)度使用
    timer = DispatchSource.makeTimerSource()
    
    // 從現(xiàn)在開始,每秒執(zhí)行一次。
    timer?.schedule(deadline: DispatchTime.now(), repeating: .seconds(1), leeway: .nanoseconds(1))
    // 5秒之后執(zhí)行任務(wù),不重復(fù)。

// timer?.schedule(deadline: DispatchTime.now() + 5, repeating: .never, leeway: .nanoseconds(1))

    timer?.setEventHandler {
        DispatchQueue.main.async {
            print("執(zhí)行任務(wù)")
        }
    }
    
    timer?.setRegistrationHandler(handler: {
        DispatchQueue.main.async {
            print("Timer開始工作了")
        }
    })
    timer?.activate()
}

執(zhí)行結(jié)果如下:

2020-11-28 02:20:00 +0000 Timer開始工作了
2020-11-28 02:20:00 +0000 執(zhí)行任務(wù)
2020-11-28 02:20:01 +0000 執(zhí)行任務(wù)
2020-11-28 02:20:02 +0000 執(zhí)行任務(wù)

2.4 GCD Timer控制方法

下面看一下Timer的一下控制方法及狀態(tài):

  • activate() : 當(dāng)創(chuàng)建完一個Timer之后,其處于未激活的狀態(tài),所以要執(zhí)行Timer,需要調(diào)用該方法。
  • suspend() : 當(dāng)Timer開始運行后,調(diào)用該方法便會將Timer掛起,即暫停。
  • resume() : 當(dāng)Timer被掛起后,調(diào)用該方法便會將Timer繼續(xù)運行。
  • cancel() : 調(diào)用該方法后,Timer將會被取消,被取消的Timer如果想再執(zhí)行任務(wù),則需要重新創(chuàng)建。

上面的這些方法如果使用不當(dāng),很容易造成APP崩潰,下面來看一下具體注意事項及建議:

  • 當(dāng)Timer創(chuàng)建完后,建議調(diào)用activate()方法開始運行。如果直接調(diào)用resume()也可以開始運行。
  • suspend()的時候,并不會停止當(dāng)前正在執(zhí)行的event事件,而是會停止下一次event事件。
  • 當(dāng)Timer處于suspend的狀態(tài)時,如果銷毀Timer或其所屬的控制器,會導(dǎo)致APP奔潰。
  • 2020-11-28 02:20:00 +0000 Timer開始工作了
    2020-11-28 02:20:00 +0000 執(zhí)行任務(wù)
    2020-11-28 02:20:01 +0000 執(zhí)行任務(wù)
    2020-11-28 02:20:02 +0000 執(zhí)行任務(wù)
    suspend()和resume()需要成對出現(xiàn),掛起一次,恢復(fù)一次,如果Timer開始運行后,在沒有suspend的時候,直接調(diào)用resume(),會導(dǎo)致APP崩潰。
  • 使用cancel()的時候,如果Timer處于suspend狀態(tài),APP崩潰。
  • 另外需要注意block的循環(huán)引用問題。

2.5 雙重循環(huán) DispatchSourceTimer

比如:我們需要一定時間情況下(數(shù)組長度*4),每隔一段時間打印對應(yīng)下標(biāo)(每個元素隔4秒打印),無限打印

在下面例子的雙重循環(huán)中使用 DispatchSourceTimer 你會發(fā)現(xiàn)print只打印了 dom some = 0 這個不是我們想要的效果

var exaltedTimer: DispatchSourceTimer?

func demo {
    let arr = [1,2,3,4]

    self.exaltedTimer = DispatchSource.makeTimerSource()
    self.exaltedTimer?.schedule(deadline: .now(), repeating: TimeInterval(arr.count*4))

    self.exaltedTimer?.setEventHandler(handler: {

        for (index, item) in arr.enumerated() {

            let timer2 = DispatchSource.makeTimerSource()
            timer2.schedule(deadline: .now()+4.0*CGFloat(index), repeating: .infinity)
            timer2.setEventHandler {
                DispatchQueue.main.async {
                    print("do some = \(index)")
                }
            }
            
            timer2.activate()


        }
    })
    self.exaltedTimer?.activate()
}

這個是因為timer2使用之后就被釋放了,所以要cancel和resume配合使用,這樣就實現(xiàn)了我們想要的效果了。

var exaltedTimer: DispatchSourceTimer?

var exaltedTimerArray: [DispatchSourceTimer] = []

func demo {

    self.exaltedTimer?.cancel()
    for subTimer in self.exaltedTimerArray {
        subTimer.cancel()
    }

    let arr = [1,2,3,4]

    self.exaltedTimer = DispatchSource.makeTimerSource()
    self.exaltedTimer?.schedule(deadline: .now(), repeating: TimeInterval(arr.count*4))

    self.exaltedTimer?.setEventHandler(handler: {

        for (index, item) in arr.enumerated() {

            let timer2 = DispatchSource.makeTimerSource()
            timer2.schedule(deadline: .now()+4.0*CGFloat(index), repeating: .infinity)
            timer2.setEventHandler {
                DispatchQueue.main.async {
                    print("do some = \(index)")
                }
            }
            
            self.exaltedTimerArray.append(timer2)
            timer2.resume()


        }
    })
    self.exaltedTimer?.resume()

參考文章

https://blog.csdn.net/guoyongming925/article/details/110224064

到此這篇關(guān)于iOS DispatchSourceTimer 定時器的具體使用的文章就介紹到這了,更多相關(guān)iOS DispatchSourceTimer 定時器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Flutter?RendererBinding作用源碼分析

    Flutter?RendererBinding作用源碼分析

    這篇文章主要為大家介紹了Flutter?RendererBinding作用和內(nèi)部一些重要的類源碼分析,希望此文能給你帶來收獲.有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • iOS App開發(fā)中UIViewController類的使用教程

    iOS App開發(fā)中UIViewController類的使用教程

    UIViewController是iOS中控制視圖的關(guān)鍵所在,這里我們將針對UIViewController的聲明周期與主要屬性和方法,來總結(jié)iOS App開發(fā)中UIViewController類的使用教程
    2016-07-07
  • 詳解iOS中Button按鈕的狀態(tài)和點擊事件

    詳解iOS中Button按鈕的狀態(tài)和點擊事件

    這篇文章先是給大家介紹iOS中Button按鈕的狀態(tài),而后又詳細(xì)介紹了iOS中按鈕點擊事件處理方式,本文介紹的很詳細(xì),有需要的朋友們可以參考借鑒,下面來一起看看吧。
    2016-09-09
  • iOS二維碼的生成和掃描

    iOS二維碼的生成和掃描

    這篇文章主要為大家詳細(xì)介紹了iOS二維碼生成和掃描的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-03-03
  • 適配iPhoneXS max和iPhoneX R的方法示例

    適配iPhoneXS max和iPhoneX R的方法示例

    這篇文章主要介紹了適配iPhoneXS max和iPhoneX R的方法示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-10-10
  • iOS實現(xiàn)日歷翻頁動畫

    iOS實現(xiàn)日歷翻頁動畫

    本文的內(nèi)容主要是在IOS中實現(xiàn)日歷翻頁的動畫,界面簡單但效果很好,以后可以運用到app中,下面一起來看看。
    2016-08-08
  • IOS 圖片存放3種方式的實現(xiàn)

    IOS 圖片存放3種方式的實現(xiàn)

    這篇文章主要介紹了IOS 圖片存放3種方式的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • iOS中5種圖片縮略技術(shù)及性能的深入探討

    iOS中5種圖片縮略技術(shù)及性能的深入探討

    縮略圖是各位iOS開發(fā)者們在日常工作中經(jīng)常會遇到的一個需求,下面這篇文章主要給大家介紹了關(guān)于iOS中5種圖片縮略技術(shù)及性能的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2018-06-06
  • IOS 中UIKit-UIPageControl利用delegate定位圓點位置

    IOS 中UIKit-UIPageControl利用delegate定位圓點位置

    這篇文章主要介紹了IOS 中UIKit-UIPageControl利用delegate定位圓點位置 的相關(guān)資料,需要的朋友可以參考下
    2017-04-04
  • iOS 13適配匯總(推薦)

    iOS 13適配匯總(推薦)

    這篇文章主要介紹了iOS 13適配匯總,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09

最新評論

平昌县| 二连浩特市| 安吉县| 万山特区| 油尖旺区| 宜昌市| 寻甸| 响水县| 梅州市| 白水县| 南投县| 桃园市| 腾冲县| 丰台区| 民权县| 伊宁市| 北海市| 德化县| 梓潼县| 湛江市| 秦皇岛市| 石嘴山市| 台东市| 辽阳市| 漳州市| 连南| 衡水市| 九寨沟县| 鸡东县| 长治县| 山阳县| 西丰县| 商都县| 辽宁省| 龙泉市| 疏勒县| 宣武区| 类乌齐县| 汶川县| 保靖县| 米易县|