iOS的使用Swift,NSOperation实现的倒计时

栏目: IOS · 发布时间: 6年前

内容简介:iOS的使用Swift,NSOperation实现的倒计时

前段时间,公司项目有个需求要求实现任务倒计时,头疼死我了,折腾了我老半天,先看最终的实现效果,如下图。当时的需求有两点要求:1、要求在当前任务关卡实现倒计时计算;2、要求在弹出来的tips页面同时也进行倒计时。

iOS的使用Swift,NSOperation实现的倒计时

timeCountDown.gif

一想到倒计时,我们可能想到的解决方案有三种;1、NStimer,2、GCD,3、NSOperation。

1、NSTimer实现倒计时

NSTimer实现计时需要注意,他默认是在runloop中的 NSDefaultRunLoopMode 计时,在这个模式下面,有滑动事件,计时将失效,此时我们需要在将timer添加到runloop中的 NSRunLoopCommonModes ,这样就不会有任何影响

let animationTimer = NSTimer.scheduledTimerWithTimeInterval(10, target: self, selector: #selector(WeeklyMissionViewController.runanimation), userInfo: nil, repeats: true) NSRunLoop.mainRunLoop().addTimer(animationTimer!, forMode: NSRunLoopCommonModes) animationTimer!.fire()

2、GCD实现倒计时

GCD实现计时需要注意的是 let _timer: dispatch_source_t 必须存储为全局变量 timer = _timer

private func setGCDTimer(weeklyMission: MissionList, type: Int) {         // 计算倒计时         let nowDate =  NSDate()         let nowUnix = nowDate.timeIntervalSince1970          let count = (weeklyMission.createdAt)! + 24 * 3600 - Int(nowUnix)                 var _timeout: Int = count         let _queue: dispatch_queue_t = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)         let _timer: dispatch_source_t = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, _queue)         timer = _timer         // 每秒执行         dispatch_source_set_timer(_timer, dispatch_walltime(nil, 0), 1 * NSEC_PER_SEC, 0)          printLog("----_timer-----")         dispatch_source_set_event_handler(_timer) { () -> Void in              if _timeout <= 0 {                 // 倒计时结束                 dispatch_source_cancel(_timer)                 dispatch_async(dispatch_get_main_queue(), { [unowned self] () -> Void in                     // 如需更新UI 代码请写在这里                     })             } else {                  print("cell:\(weeklyMission.mission)---\(_timeout)")                 _timeout -= 1                 let hours = _timeout / 3600                 let hoursSec = hours * 3600                 let minutes = (_timeout - hoursSec) / 60                 let seconds = _timeout - hoursSec - minutes * 60                  dispatch_async(dispatch_get_main_queue(), {  [unowned self] in                     let timeText = "\(String(format: "%.2d",hours)):\(String(format: "%.2d",minutes)):\(String(format: "%.2d",seconds))"                     // 如需更新UI 代码请写在这里                     })             }         }         dispatch_resume(_timer)     }

3、NSOperation实现倒计时以上两种实现的计时,有个很明显的缺点就是,不可控!他们二者开启一个计时器之后,没法方便的控制他停止,继续;但是NSOperation不同,他有cancel方法,我们可以拿到对应的operation,然后操作他,可控性好。主要代码如下:

// //  TimeCountDownManager.swift //  leapParent // //  Created by romance on 16/9/19. //  Copyright © 2016年 Firstleap. All rights reserved. //  import UIKit  /// 计时中回调 typealias TimeCountingDownTaskBlock = (timeInterval: NSTimeInterval) -> Void // 计时结束后回调 typealias TimeFinishedBlock = (timeInterval: NSTimeInterval) -> Void private var shareInstance = TimeCountDownManager()  final class TimeCountDownManager: NSObject {     // 单利     class var sharedInstance : TimeCountDownManager {         return shareInstance     }      var pool: NSOperationQueue      override init() {         pool = NSOperationQueue()         super.init()     }      /**      *  开始倒计时,如果倒计时管理器里具有相同的key,则直接开始回调。      *      *  @param Key         任务key,用于标示唯一性      *  @param timeInterval 倒计时总时间,      *  @param countingDown 倒计时时,会多次回调,提供当前秒数      *  @param finished     倒计时结束时调用,提供当前秒数,值恒为 0      */     func scheduledCountDownWith(key: String, timeInteval: NSTimeInterval, countingDown:TimeCountingDownTaskBlock?,finished:TimeCountingDownTaskBlock?) {          var task: TimeCountDownTask?         if coundownTaskExistWith(key, task: &task) {             task?.countingDownBlcok = countingDown             task?.finishedBlcok = finished             if countingDown != nil {                 countingDown!(timeInterval: (task?.leftTimeInterval) ?? 60)             }         } else {             task = TimeCountDownTask()             task?.leftTimeInterval = timeInteval             task?.countingDownBlcok = countingDown             task?.finishedBlcok = finished             task?.name = key              pool.addOperation(task!)         }     }      /**      *  查询倒计时任务是否存在      *      *  @param akey 任务key      *  @param task 任务      *  @return YES - 存在, NO - 不存在      */     func coundownTaskExistWith(key: String,inout task: TimeCountDownTask? ) -> Bool {         var taskExits = false          for (_, obj)  in pool.operations.enumerate() {             let temptask = obj as! TimeCountDownTask             if temptask.name == key {                 task = temptask                 taskExits = true //                print("coundownTaskExistWith#####\(temptask.leftTimeInterval)")                 break             }         }         return taskExits     }      /**      *  取消所有倒计时任务      */     func cancelAllTask() {         pool.cancelAllOperations()     }      /**      *  挂起所有倒计时任务      */     private func suspendAllTask() {         pool.suspended = true     } }   final class TimeCountDownTask: NSOperation {     var leftTimeInterval: NSTimeInterval = 0     var countingDownBlcok: TimeCountingDownTaskBlock?     var finishedBlcok: TimeFinishedBlock?      override func main() {          if self.cancelled {             return         }                 while leftTimeInterval > 0 {             print("leftTimeInterval----\(leftTimeInterval)")              if self.cancelled {                 return             }             leftTimeInterval -= 1             dispatch_async(dispatch_get_main_queue(), {                 if self.countingDownBlcok != nil {                     self.countingDownBlcok!(timeInterval: self.leftTimeInterval)                 }             })             NSThread.sleepForTimeInterval(1)         }          dispatch_async(dispatch_get_main_queue()) {             if self.cancelled {                 return             }             if self.finishedBlcok != nil {                 self.finishedBlcok!(timeInterval: 0)             }         }     } }

稍微解析下以上代码, TimeCountDownManager 是定时器管理类,是个单利,可以管理app中所有需要倒计时的task, TimeCountDownTask 是具体的用来处理倒计时的NSOperation子类,大家还可以在我的基础上进行完善,比如cancel具体taskIdentifier的task,suspended具体的task,等等!

整个demo代码的GitHub地址,希望对大家有用,喜欢的希望大家点赞,评论,转发,关注我啊!让文章下面的:hearts:点亮哦!


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

机器学习

机器学习

(美)Tom Mitchell / 曾华军、张银奎、等 / 机械工业出版社 / 2008-3 / 35.00元

《机器学习》展示了机器学习中核心的算法和理论,并阐明了算法的运行过程。《机器学习》综合了许多的研究成果,例如统计学、人工智能、哲学、信息论、生物学、认知科学、计算复杂性和控制论等,并以此来理解问题的背景、算法和其中的隐含假定。《机器学习》可作为计算机专业 本科生、研究生教材,也可作为相关领域研究人员、教师的参考书。一起来看看 《机器学习》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

随机密码生成器
随机密码生成器

多种字符组合密码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具