【问题标题】:Timer.scheduledTimer Swift 3 pre-iOS 10 compatibilityTimer.scheduledTimer Swift 3 pre-iOS 10 兼容性
【发布时间】:2016-12-06 08:29:58
【问题描述】:

我需要安排一个计时器来每秒触发一个函数,但我看到在 Xcode 8 beta 3 中,scheduledTimer 仅适用于 iOS 10。

在 iOS 9 或之前的版本中,有没有其他方法可以使用计时器?

Timer.scheduledTimer(withTimeInterval: 1, repeats: true, block: { (timer) in print("Hi!")})

【问题讨论】:

    标签: ios swift ios9 ios10 xcode8-beta3


    【解决方案1】:

    您可以使用以下简单的 shim 为 iOS 10 之前的版本提供新的基于块的计时器:

    class TimerShim {
        private var timer: Timer?
        private let block: (Timer) -> Void
    
        private init(timeInterval interval: TimeInterval, repeats: Bool, block: @escaping (Timer) -> Void) {
            self.block = block
            timer = Timer.scheduledTimer(timeInterval: interval, target: self, selector: #selector(timerDidFire), userInfo: nil, repeats: repeats)
        }
    
        class func scheduledTimer(withTimeInterval interval: TimeInterval, repeats: Bool, block: @escaping (Timer) -> Void) -> Timer {
            return TimerShim(timeInterval: interval, repeats: repeats, block: block).timer!
        }
    
        @objc private func timerDidFire() {
            block(timer!)
        }
    }
    

    使用示例:

    TimerShim.scheduledTimer(withTimeInterval: 5, repeats: false) { _ in
        print("boom!")
    }
    

    【讨论】:

      【解决方案2】:

      以下是兼容的示例代码:

      if #available(iOS 10.0, *) {
          Timer.scheduledTimer(withTimeInterval: 15.0, repeats: true){_ in
              // Your code is here:
              self.myMethod()
          }
      } else {      
          Timer.scheduledTimer(timeInterval: 15.0, target: self, selector: #selector(self.myMethod), userInfo: nil, repeats: true)
      }
      

      //你的方法或函数:

      // MARK: -  Method
      
      @objc func myMethod() {
          print("Hi, How are you.")
      }
      

      【讨论】:

        【解决方案3】:

        解决了

        Timer.scheduledTimer(timeInterval: 1,
                                   target: self,
                                 selector: #selector(self.updateTime),
                                 userInfo: nil,
                                  repeats: true)
        

        【讨论】:

        • 如果您愿意,可以使用if #available(iOS 10, *) { //iOS 10 code } else { //iOS 9 code } 来支持两者,具体取决于操作系统版本。
        • 我需要添加这样的目标函数:@objc func updateTime() {}
        • 下面的帖子也值得一看,看看定时器是如何停止的。如果不手动删除,它可能无法从运行循环中正确删除。
        • 你好,我是 swift 新手,只是一个基本问题,userInfo 在 scheduleTimer 函数中代表什么??
        • 嗨@prasoonraj,我想这意味着您可以在每次触发计时器时传递包含任何有用信息的字典。
        【解决方案4】:
        Timer.scheduledTimer
        

        放到主线程中。

        【讨论】:

          【解决方案5】:

          为 swift 3 更新:

          如果您想将 Timer 用于某些延迟或在项目中的代码行下方使用的任何其他目的;

          //函数定义:

          func usedTimerForDelay()  {
              Timer.scheduledTimer(timeInterval: 0.3,
                                   target: self,
                                   selector: #selector(self.run(_:)),
                                   userInfo: nil, 
                                   repeats: false)
          }
          
          func run(_ timer: AnyObject) {
                print("Do your remaining stuff here...")
          
          }
          

          // 函数调用:

          self.usedTimerForDelay()
          

          注意:- 您可以根据需要更改时间间隔。

          //享受编码..!

          【讨论】:

            【解决方案6】:

            使用 swift3 运行计时器,

            var timer: Timer?
            
            func startTimer() {
            
                if timer == nil {
                    timer = Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(self.loop), userInfo: nil, repeats: true)
                }
            }
            
            func stopTimer() {
                if timer != nil {
                    timer?.invalidate()
                    timer = nil
                }
            }
            
            func loop() {
                let liveInfoUrl = URL(string: "http://192.168.1.66/api/cloud/app/liveInfo/7777")
                let task = URLSession.shared.dataTask(with: liveInfoUrl! as URL) {data, response, error in
                    guard let data = data, error == nil else { return }
                    print(String(data: data, encoding: String.Encoding(rawValue: String.Encoding.utf8.rawValue)) ?? "aaaa")
                }
                task.resume()
            }
            

            当你不使用它时释放它。

            一旦安排在运行循环上,计时器就会在指定的时间触发 间隔,直到它失效。非重复计时器无效 自己开火后立即。但是,对于重复计时器,您 必须自己通过调用其 invalidate() 来使计时器对象无效 方法。

            【讨论】:

            • 很好地指出了定时器的 .invalidate() 结尾以及运行循环。
            • 不需要对计时器进行 nil 检查。它已经是可选的了。
            【解决方案7】:

            斯威夫特 3

            func runCode(in timeInterval:TimeInterval, _ code:@escaping ()->(Void))
            {
                DispatchQueue.main.asyncAfter(
                    deadline: .now() + timeInterval,
                    execute: code)
            }
            
            func runCode(at date:Date, _ code:@escaping ()->(Void))
            {
                let timeInterval = date.timeIntervalSinceNow
                runCode(in: timeInterval, code)
            }
            
            func test()
            {
                runCode(at: Date(timeIntervalSinceNow:2))
                {
                    print("Hello")
                }
            
                runCode(in: 3.0)
                {
                    print("World)")
                }
            }
            

            【讨论】:

              【解决方案8】:

              正确的形式是:

              Timer.scheduledTimer(withTimeInterval: 2, repeats: false){_ in
                 "Here your code method"
              }
              

              【讨论】:

              • 这不是在 iOS 9 上运行的,但是问的问题是
              • 这段代码也在 swift 4.2 上运行。感谢它。
              猜你喜欢
              • 1970-01-01
              • 2017-01-22
              • 2015-12-08
              • 1970-01-01
              • 2016-03-18
              • 2017-02-11
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多