iOS-簡單易用的GCD計時器

前言

??好久沒更新文章了酪惭,還是給自己立一個flag每周至少更新一篇文章,可能文章的質量還不是很如意者甲,希望通過寫文章來提高自己文筆春感,以及記錄自己學習中的遇到的問題解決方案。
??在學習iOS過程中过牙,想定大家對于定時器都不陌生,在日常開發(fā)中總會碰到需要計時器的功能纺铭,常見的定時器有NSTimer寇钉、GCD、CADisplayLink舶赔。網(wǎng)上也有很多的教程介紹三者的區(qū)別扫倡,今天主要講的是GCD這種方式使用以及封裝。

三者概括區(qū)別

優(yōu)點 缺點
NSTimer 使用簡單 受Runloop影響會導致計時不精準
CADisplayLink 精度高 ???? CPU負載的時候會影響觸發(fā)事件竟纳,且觸發(fā)事件大于觸發(fā)間隔會導致掉幀現(xiàn)象撵溃。
GCD 較精準 代碼較多,基本不受其他影響

總結:NSTimer和CADisplayLink易受影響锥累,而GCD雖然代碼多缘挑,但是可控性非常強。

GCD

/** 獲取一個全局的線程來運行計時器*/
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
/** 創(chuàng)建一個計時器*/
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
/** 設置計時器, 這里是每10毫秒執(zhí)行一次*/
dispatch_source_set_timer(timer, dispatch_walltime(nil, 0), 10*NSEC_PER_MSEC, 0);
/** 設置計時器的里操作事件*/
dispatch_source_set_event_handler(timer, ^{
    //do you want....
});
開啟桶略、繼續(xù)已暫停的定時器
dispatch_resume(timer);
暫停定時器
/** 掛起的時候注意语淘,多次暫停的操作會導致線程鎖的現(xiàn)象诲宇,即多少次暫停,
*   對應多少次的繼續(xù)操作惶翻,即dispatch_suspend和dispatch_resume
*   是成對出現(xiàn)的姑蓝,計時器才會繼續(xù)工作。
*/
dispatch_suspend(timer);
結束定時器
dispatch_source_cancel(timer);

構思封裝

寫代碼之前構思好功能模塊以及會遇到的問題的解決方案吕粗、代碼邏輯纺荧,再來下手寫代碼,會有事半功倍的效果颅筋。
  • 必然包含開始宙暇、暫停、繼續(xù)垃沦、停止客给、重置功能
  • 時間計算過程中因浮點數(shù)計算會丟失精度,計算過程應采用NSDecimal
  • 時間轉換考慮到精度以及便利性肢簿,采用系統(tǒng)的時間轉換方法靶剑,時區(qū)置為GMT
  • 由于APP進入后臺,若未開啟后臺任務的開關池充,計時器將會停止桩引,再次進入APP又會繼續(xù),故采用監(jiān)聽app狀態(tài)的方式記錄APP進入后臺與前臺的時間戳收夸,并與截止時間相比坑匠,是否繼續(xù)計時還是結束計時并回調。
  • 計時器返回的結果若采用字符串則還需處理卧惜,故使用了一個時間類來把結果返回厘灼,可以進行自定義操作
  • 倒計時的結果返回和結束通知采用閉包形式

部分代碼

/** app進入后臺*/
- (void)appDidEnterBackground{
    [self suspend];
    NSDate *date = [[NSDate alloc] init];
    NSDateFormatter *format = [[NSDateFormatter alloc] init];
    format.dateFormat = @"yyyy-MM-dd HH:mm:ss:SSS";
    self.appDidEnterBackgroundTime = [date timeIntervalSince1970];
}

/** app進入前臺*/
- (void)appDidEnterForeground{
    NSDate *date = [[NSDate alloc] init];
    NSDateFormatter *format = [[NSDateFormatter alloc] init];
    format.dateFormat = @"yyyy-MM-dd HH:mm:ss";
    self.appDidEnterForegroundTime = [date timeIntervalSince1970];
    [self reCalculateMinder];
}
/** 不失精度加減乘除計算結果*/

- (NSDecimalNumber *)value: (NSTimeInterval)value 
                byOpration: (OMDecimalOprationType)byOpration       
                 percision:  (NSInteger)percision 
                withValue: (NSTimeInterval)withValue{

    NSDecimalNumber *number = [self numberValueWithString: value];
    NSDecimalNumber *withNumber = [self numberValueWithString: withValue];  
    NSDecimalNumberHandler *handler = [NSDecimalNumberHandler  decimalNumberHandlerWithRoundingMode: NSRoundPlain  scale: percision raiseOnExactness: NO  raiseOnOverflow: NO  raiseOnUnderflow: NO  raiseOnDivideByZero: YES];

switch (byOpration) {
    case  OMDecimalOprationTypeAdd:
      return [number decimalNumberByAdding: withNumber withBehavior:handler];
      break;
    case  OMDecimalOprationTypeSubtract:
      return [number decimalNumberBySubtracting: withNumber withBehavior: handler];
      break;
   case  OMDecimalOprationTypeDivide:
      return [number decimalNumberByDividingBy: withNumber withBehavior: handler];
      break;
  case  OMDecimalOprationTypeMultiple:
      return [number decimalNumberByMultiplyingBy: withNumber withBehavior: handler];
      break;
  default:
      return nil;
      break;
}
@property (nonatomic, strong) OMTimer *timer;
self.timer = [[OMTimer alloc] init];
self.timer.timerInterval = 30;
self.timer.precision = 100;
self.timer.isAscend = NO;
self.timer.progressBlock = ^(OMTime *progress) {
     NSLog(@"%@:%@:%@:%@", progress.hour, progress.minute, progress.second, progress.millisecond;
};
self.timer.completion = ^{
    NSLog(@"complete done!");
};

Swift版本

??最近喜歡上了OC,如有小伙伴需要Swift的版本的話可以留言或者私我咽瓷,可以在寫個Swift版本设凹,。

結語

??使用簡單茅姜,只需要把OMTimer.h和OMTimer.m拖入你的工程即可闪朱,滿足大數(shù)的場景,可倒計時亦可增加計時钻洒,全部代碼已在Github<https://github.com/oymuzi/OMKit/>上面奋姿,如對你有幫助,希望得到你的一顆小星星?素标,謝謝称诗。
??如有疑問,直接留言或者發(fā)送郵件給我 admin@mypup.cn

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末头遭,一起剝皮案震驚了整個濱河市粪狼,隨后出現(xiàn)的幾起案子退腥,更是在濱河造成了極大的恐慌,老刑警劉巖再榄,帶你破解...
    沈念sama閱讀 210,914評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件狡刘,死亡現(xiàn)場離奇詭異,居然都是意外死亡困鸥,警方通過查閱死者的電腦和手機嗅蔬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評論 2 383
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來疾就,“玉大人澜术,你說我怎么就攤上這事♀” “怎么了鸟废?”我有些...
    開封第一講書人閱讀 156,531評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長姑荷。 經常有香客問我盒延,道長,這世上最難降的妖魔是什么鼠冕? 我笑而不...
    開封第一講書人閱讀 56,309評論 1 282
  • 正文 為了忘掉前任添寺,我火速辦了婚禮,結果婚禮上懈费,老公的妹妹穿的比我還像新娘计露。我一直安慰自己,他們只是感情好憎乙,可當我...
    茶點故事閱讀 65,381評論 5 384
  • 文/花漫 我一把揭開白布票罐。 她就那樣靜靜地躺著,像睡著了一般泞边。 火紅的嫁衣襯著肌膚如雪该押。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,730評論 1 289
  • 那天繁堡,我揣著相機與錄音沈善,去河邊找鬼乡数。 笑死椭蹄,一個胖子當著我的面吹牛,可吹牛的內容都是我干的净赴。 我是一名探鬼主播绳矩,決...
    沈念sama閱讀 38,882評論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼玖翅!你這毒婦竟也來了翼馆?” 一聲冷哼從身側響起割以,我...
    開封第一講書人閱讀 37,643評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎应媚,沒想到半個月后严沥,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 44,095評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡中姜,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,448評論 2 325
  • 正文 我和宋清朗相戀三年消玄,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片丢胚。...
    茶點故事閱讀 38,566評論 1 339
  • 序言:一個原本活蹦亂跳的男人離奇死亡翩瓜,死狀恐怖,靈堂內的尸體忽然破棺而出携龟,到底是詐尸還是另有隱情兔跌,我是刑警寧澤,帶...
    沈念sama閱讀 34,253評論 4 328
  • 正文 年R本政府宣布峡蟋,位于F島的核電站坟桅,受9級特大地震影響,放射性物質發(fā)生泄漏层亿。R本人自食惡果不足惜桦卒,卻給世界環(huán)境...
    茶點故事閱讀 39,829評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望匿又。 院中可真熱鬧方灾,春花似錦、人聲如沸碌更。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽痛单。三九已至嘿棘,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間旭绒,已是汗流浹背鸟妙。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留挥吵,地道東北人重父。 一個月前我還...
    沈念sama閱讀 46,248評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像忽匈,于是被迫代替她去往敵國和親房午。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,440評論 2 348

推薦閱讀更多精彩內容

  • 1丹允、通過CocoaPods安裝項目名稱項目信息 AFNetworking網(wǎng)絡請求組件 FMDB本地數(shù)據(jù)庫組件 SD...
    陽明先生_X自主閱讀 15,969評論 3 119
  • 1.bss段( bss segment ) bss段通常是指用來存放程序中未初始化的全局變量和靜態(tài)變量的一塊內存區(qū)...
    dozening007閱讀 5,291評論 2 5
  • 音樂是高雅的藝術郭厌,無數(shù)仁人志士在歷史長河中前赴后繼袋倔,為音樂拋頭顱灑熱血,鍛造出一幕幕贊歌折柠。 我熱愛音樂宾娜,但我的熱愛...
    盛世阿明閱讀 184評論 0 1
  • 想要安裝pygame,利用這個包來畫一些幾何圖形: 于是在命令行中打出下面這行命令扇售,想通過pip的豆瓣鏡像來幫我把...
    cinderlv閱讀 3,608評論 0 1