Timer.scheduledTimer在Swift 3中不起作用

Jin*_*ian 16 timer ios swift swift3

我想func adjustmentBestSongBpmHeartRate() 每1.1秒调用一次方法.我用过Timer,但它不起作用.我已阅读该文档并发现了大量示例代码,它仍然可以正常工作!我错过了什么吗?

 timer = Timer.scheduledTimer(timeInterval: 1.1, target: self, selector: #selector(self.adjustmentBestSongBpmHeartRate), userInfo: nil, repeats: false)
 timer.fire()

 func adjustmentBestSongBpmHeartRate() {
    print("frr")
 }
Run Code Online (Sandbox Code Playgroud)

Nic*_*247 27

我发现在OperationQueue操作中创建计时器不起作用.我认为这是因为没有runloop.

因此,以下代码修复了我的问题:

DispatchQueue.main.async {
    // timer needs a runloop?
    self.timeoutTimer = Timer.scheduledTimer(timeInterval: self.timeout, target: self, selector: #selector(self.onTimeout(_:)), userInfo: nil, repeats: false)
}
Run Code Online (Sandbox Code Playgroud)

  • 我正在后台线程中安排计时器。将此计时器调度从后台线程移动到主线程,并且它开始按照我的预期工作。谢啦。 (3认同)
  • 我的情况..现在看起来很明显。谢谢! (2认同)

Dun*_*n C 20

带选择器的定时器方法应该有一个参数:定时器本身.因此,您的代码应该看起来像这样:1

Timer.scheduledTimer(timeInterval: 1.1, 
    target: self, 
    selector: #selector(self.adjustmentBestSongBpmHeartRate(_:), 
    userInfo: nil, 
    repeats: false)

@objc func adjustmentBestSongBpmHeartRate(_ timer: Timer) {
    print("frr")
 }
Run Code Online (Sandbox Code Playgroud)

请注意,如果您的应用仅在iOS> = 10上运行,则可以使用新方法来调用块而不是目标/选择器.更清洁,更安全类型:

class func scheduledTimer(withTimeInterval interval: TimeInterval, 
    repeats: Bool, 
    block: @escaping (Timer) -> Void) -> Timer
Run Code Online (Sandbox Code Playgroud)

该代码如下所示:

 timer = Timer.scheduledTimer(withTimeInterval: 1.1, 
        repeats: false) {
    timer in
    //Put the code that be called by the timer here.
    print("frr")
    }
Run Code Online (Sandbox Code Playgroud)

请注意,如果您的计时器块/闭包需要访问您班级中的实例变量,则必须特别注意self.对于那种代码,这是一个很好的模式:

 timer = Timer.scheduledTimer(withTimeInterval: 1.1, 
        repeats: false) {

    //"[weak self]" creates a "capture group" for timer
    [weak self] timer in

    //Add a guard statement to bail out of the timer code 
    //if the object has been freed.
    guard let strongSelf = self else {
        return
    }
    //Put the code that be called by the timer here.
    print(strongSelf.someProperty)
    strongSelf.someOtherProperty = someValue
    }
Run Code Online (Sandbox Code Playgroud)

编辑:

1:我应该补充一点,你在选择器中使用的方法必须使用Objective-C动态调度.您可以使用@objc限定符声明方法,可以声明使用限定符定义选择器的整个类,@objc也可以使定义选择器的类成为NSObject继承自的子类或任何类NSOBject.(定义计时器在a中调用的方法是很常见的UIViewController,它是一个子类NSObject,因此它"正常工作".

编辑

在Swift 4中,需要从Objective-C调用的方法现在需要使用@objc限定符单独标记."它只是有效"评论不再适用.


Jor*_*ego 10

斯威夫特3

在我的情况下,在我向我的方法添加了@obj前缀后,它工作了

Class TestClass {
   private var timer: Timer?

   func start() {
        guard timer == nil else { return }
        timer = Timer.scheduledTimer(timeInterval: 60, target: self, selector: #selector(handleMyFunction), userInfo: nil, repeats: false)
    }

    func stop() {
        guard timer != nil else { return }
        timer?.invalidate()
        timer = nil
    }


    @objc func handleMyFunction() {
        // Code here
    }
}
Run Code Online (Sandbox Code Playgroud)


Nik*_*ure 5

尝试这个 -

if #available(iOS 10.0, *) {
     self.timer = Timer.scheduledTimer(withTimeInterval: 0.2, repeats: false, block: { _ in
         self.update()
     })
} else {
     self.timer = Timer.scheduledTimer(timeInterval: 0.2, target: self, selector: #selector(self.update), userInfo: nil, repeats: false)
}
Run Code Online (Sandbox Code Playgroud)

大多数情况下,问题可能出在iOS的移动版上。


Sha*_*med 5

Swift 5、Swift 4 简单方法仅使用 Dispatch Queue Async 进行调用

DispatchQueue.main.async 
{
   self.andicator.stopAnimating()
   self.bgv.isHidden = true

   Timer.scheduledTimer(withTimeInterval: 1.0, repeats: false, block: { _ in

       obj.showAlert(title: "Successfully!", message: "Video save successfully to Library directory.", viewController: self)

   })
}
Run Code Online (Sandbox Code Playgroud)