我想在未来安排一个函数调用。我正在使用 Swift。
我想回调一个私有(private)方法并返回一个 Promise(来自 PromiseKit)
我见过的所有例子都用到了
NSTimer.scheduledTimerWithTimeInterval(ti: NSTimeInterval, target: AnyObject, selector: Selector, userInfo: AnyObject?, repeats: Bool)
很好。我试过了
NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "connect", userInfo: nil, repeats: false)
失败,No method declared with Objective-C selector 'connect'
。
Objective-C 在这里做什么??
无论如何,建议我在方法connect
前添加@objc
。美好的。好吧,我不能,因为显然 Method 不能被标记为 @objc 因为它的结果类型不能在 Objective-C 中表示
如果我想使用 objective-C,我就不会写 Swift...
还有一个scheduledTimerWithTimeInterval
就是
NSTimer.scheduledTimerWithTimeInterval(ti: NSTimeInterval, invocation: NSInvocation, repeats: Bool)
但据我所知,NSInvocation
不是 Swift 的东西...
所以我最终创建了一个包装器,它除了调用 connect
并返回 Objective C 可以理解的 Void
之外什么都不做。它有效,但感觉很愚蠢。有没有更好的 Swift 方法?
奖金:为什么 javascript 可以像 setTimeout(this.connect, 1)
那样简单地做到这一点,而 Swift 没有我能找到的内置方式?
最佳答案
从 iOS 10 和 Swift 3 开始,可以将 (NS)Timer 与 block 闭包一起使用,从而避免在计时器触发时调用 Objective-C 选择器:
if #available(iOS 10.0, *) {
Timer.scheduledTimer(withTimeInterval: 1.0, repeats: false, block: { (Timer) in
self.connect() // per the OP's example
})
}
除了避免使用 @objc
装饰器之外,使用此技术还允许您调用包含非 Objective-C 兼容参数类型(例如枚举和可选参数)的方法。
Re: setTimeout(this.connect, 1)
来自 Javascript,如果你不需要取消它,在 Swift 3 中更直接的类比可能是:
DispatchQueue.Main.asyncAfter(deadline: .now() + 1.0, execute { self.connect() })
考虑到您实际上可以选择要在哪个线程上运行,这非常接近 ;-)
关于Swift - scheduledTimerWithTimeInterval - NSInvocation,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38194513/