如何在Swift 3中创建带有可选参数的函数选择器



我需要创建一个这样的定时器:

timer = Timer.scheduledTimer(timeInterval: 2, target: self, selector: #selector(dismissNotification(completion:)), userInfo: nil, repeats: false)
func dismissNotification(completion: (() -> ())? = nil) { ... }

但是没有显示任何原因就崩溃了。为什么会这样?如何解决这个问题呢?

(NS)Timer只允许两种类型的操作:

不带参数

  • func timerFireMethod()

使用单个参数传递受影响的(NS)Timer实例

  • func timerFireMethod(_ timer : Timer)

但是在iOS 10/macOS 10.12中,你可以使用一个带有闭包的新API

class func scheduledTimer(withTimeInterval interval: TimeInterval, 
                                            repeats: Bool, 
                                              block: @escaping (Timer) -> Void) -> Timer

函数崩溃,因为计时器将自己传递给了选择器方法。而选择器方法需要一个匿名函数。

你可以这样做:

timer = Timer.scheduledTimer(timeInterval: 2, target: self, selector: #selector(dismissNotification(timer:)), userInfo: nil, repeats: false)
func dismissNotification(timer: Timer) {
    //call dismissNotification(completion) here
}
func dismissNotification(completion: (() -> ())? = nil) { ... }

还可以使用Timer.userInfo属性将额外的数据传递给dismissNotification(timer: Timer)函数。

完成处理程序需要有签名

 func dismissNotification(completion: Timer) { ... }

也可以省略Timer参数:

 func dismissNotification() { ... }

Dispatch也提供类似的功能,允许代码在任意队列上执行:

// It's necessary to keep a reference to timer
let timer = DispatchSource.makeTimerSource(queue: DispatchQueue.main)
timer.scheduleRepeating(deadline: DispatchTime.now(), interval: DispatchTime.seconds(2))
timer.setEventHandler() { ... } 
timer.resume()

最新更新