
前言:
了解swift GCD 與OC GCD請看我的其他總結(jié)文章,這篇文章只是對swift GCD定時器的一個實(shí)例探討,如果有什么不對,請各位指正。
swift CGD 地址
OC CGD 地址
一、 swift DispatchSourceTimer
- 創(chuàng)建方法
*timer要全局定義,局部定義初始化生命周期太短,不會執(zhí)行回調(diào)
//1. 指定線程 行的)
/**創(chuàng)建
* flags: 一個數(shù)組,(暫時不知干嗎用的,請大神指教)
* queue: timer 在那個隊(duì)列里面執(zhí)
*/
let timer = DispatchSource.makeTimerSource(flags: [], queue: DispatchQueue.global())
//2. 默認(rèn)主線程
let timer = DispatchSource.makeTimerSource()
- 設(shè)置回調(diào)參數(shù)
分為單次執(zhí)行與循環(huán)執(zhí)行
/**
wallDeadline: 什么時候開始
leeway: 調(diào)用頻率,即多久調(diào)用一次
*/
//循環(huán)執(zhí)行,馬上開始,間隔為1s,誤差允許10微秒
timer?.scheduleRepeating(deadline: DispatchTime.now(), interval: .seconds(countDownFrequency), leeway: .milliseconds(10))
//單次執(zhí)行
timer?.scheduleOneshot(wallDeadline: .now(), leeway: .microseconds(10))
- 回調(diào)方法
如果在子線程,別忘了回到主線程
///執(zhí)行timer
self.timer?.setEventHandler(handler: {
DispatchQueue.main.sync {
}
})
- 開始執(zhí)行
timer?.resume()
二、 定時器 demo對比
- oc:
c語言的函數(shù)
//0.創(chuàng)建隊(duì)列
dispatch_queue_t queue = self.queue;
[self.modelArray enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
[obj setValue:@"0" forKey:self.modelCountDownKey];
}];
//1.創(chuàng)建GCD中的定時器
/*
第一個參數(shù):創(chuàng)建source的類型 DISPATCH_SOURCE_TYPE_TIMER:定時器
第二個參數(shù):0
第三個參數(shù):0
第四個參數(shù):隊(duì)列
*/
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
self.timer = timer;
//2.設(shè)置定時器
/*
第一個參數(shù):定時器對象
第二個參數(shù):DISPATCH_TIME_NOW 表示從現(xiàn)在開始計(jì)時
第三個參數(shù):間隔時間 GCD里面的時間最小單位為 納秒
第四個參數(shù):精準(zhǔn)度(表示允許的誤差,0表示絕對精準(zhǔn))
*/
dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, self.countDownUnit * NSEC_PER_SEC, 0 * NSEC_PER_SEC);
//3.要調(diào)用的任務(wù)
dispatch_source_set_event_handler(timer, ^{
dispatch_async(self.queue, ^{
[self lookingForATimelyModelArray:self.modelArray];
dispatch_async(dispatch_get_main_queue(), ^{
if (self.countdownDataFredbackWithBlock) {
self.countdownDataFredbackWithBlock();
}
});
});
});
//4.開始執(zhí)行
dispatch_resume(timer);
- swift:
中的GCD則是一個對象
/**創(chuàng)建timer
* flags: 一個數(shù)組,(暫時不知干嗎用的,請大神指教)
* queue: timer 在那個隊(duì)列里面執(zhí)行
*/
self.timer = DispatchSource.makeTimerSource(flags: [], queue: DispatchQueue.global())
///設(shè)置timer的計(jì)時參數(shù)
/**
wallDeadline: 什么時候開始
leeway: 調(diào)用頻率,即多久調(diào)用一次
*/
//循環(huán)執(zhí)行,馬上開始,間隔為1s,誤差允許10微秒
timer?.scheduleRepeating(deadline: DispatchTime.now(), interval: .seconds(countDownFrequency), leeway: .milliseconds(10))
///執(zhí)行timer
self.timer?.setEventHandler(handler: {
DispatchQueue.main.sync {
// 回調(diào) 回到了主線程
}
})
///執(zhí)行timer
self.timer?.resume()
三、小組件封裝
1. 組件構(gòu)成:
組件分為三部分:
1.PYButton_CountDown: 帶有定時器的button的封裝(可以是類擴(kuò)展,這里采用繼承)
2. PYTextField_LTBView:對帶有左邊label,中間textField,右邊PYButton_CountDown的的封裝
3. PYTextField_LTBArrayView: 根據(jù)外部傳遞的信息創(chuàng)建多層上下結(jié)構(gòu)的PYTextField_LTBView
2. 單元組件
Button的封裝(PYButton_CountDown)
大體思路:
這里可以用分類,本次封裝用的是繼承方法封裝。
1.創(chuàng)建一個定時器,告訴定時器的倒計(jì)時總數(shù)var totalTime: NSInteger = 60
2.提供開啟和取消定時器的方法func timerResume()func timerCancel()
3.當(dāng)定時器啟動的時候,按鈕是不能點(diǎn)擊的,當(dāng)?shù)褂?jì)時完成在次可以點(diǎn)擊
4.倒計(jì)時Button的UI顯示的字符串的擴(kuò)展,要通過一個閉包回調(diào)當(dāng)前時間,并且要求閉包返回一個字符串,進(jìn)行UI展示
func contDownCallBackFunc(countDownCallBack: @escaping (_ leftTime: NSInteger)->(String)?)
- 屬性 (public)
///計(jì)時器
var timer: DispatchSourceTimer?
/// 倒計(jì)時總數(shù) (默認(rèn)60)
var totalTime: NSInteger = 60
var currentTime: NSInteger = 60
/// 倒計(jì)時頻率 (默認(rèn)1s)
var countDownFrequency: NSInteger = 1
///normal狀態(tài)的background color
var normalBackgroundColor: UIColor?
///倒計(jì)時時候的background color
var selectedBackgroundColor: UIColor?
///normal 狀態(tài)下的字符
var normalStr: String = "" {
didSet {
self.setTitle(normalStr, for: .normal)
}
}
///倒計(jì)時狀態(tài)下的字符
var selectedStr: String {
didSet {
self.setTitle(selectedStr, for: .selected)
}
}
/// 改變selected的時候調(diào)用
var changeSelectedCallBack: ((_ isSelected: Bool)->())?
///倒計(jì)時的回調(diào)屬性
var countDownCallBack: ((_ leftTime: NSInteger)->(String)?)?
- 方法
///倒計(jì)時的回調(diào) 用來拼接字符串用
///
/// - Parameter countDownCallBack: 倒計(jì)時剩余時間 回調(diào) 返回自己拼接的字符串
func contDownCallBackFunc(countDownCallBack: @escaping (_ leftTime: NSInteger)->(String)?) {
self.countDownCallBack = countDownCallBack
}
/// 開啟定時器
func timerResume() {
self.setUPTimer()
}
/// 停止定時器
func timerCancel() {
self.stopTimer()
}