我正在尝试使用timer实现一个函数,并且发现在通过“URLSession.dataTask”的回调函数调用它时不执行timer。
在下面的情况下,调用“callee”函数。
class TimerClass {
func caller() {
timer = Timer.scheduledTimer(timeInterval: 0.1,
target: self,
selector: #selector(callee),
userInfo: nil,
repeats: false)
}
func callee() {
print(“OK”)
}
}
class AnyClass {
func any() {
let timer:TimerClass=TimerClass()
timer.caller()
}
}
但是没有调用“callee”以下。 (我已确认已执行“来电”功能)
class TimerClass {
func caller() {
timer = Timer.scheduledTimer(timeInterval: 0.1,
target: self,
selector: #selector(callee),
userInfo: nil,
repeats: false)
}
func callee() {
print(“OK”)
}
}
class AnyClass {
func any() {
func cb(data:Data?, response:URLResponse?, err:Error?) {
let timer:TimerClass=TimerClass()
timer.caller()
}
let task = URLSession.shared.dataTask(with: request as URLRequest, completionHandler: cb)
.
.
.
}
}
我想也许是因为它是由子任务执行的 任何人都可以告诉我如何更正代码?
答案 0 :(得分:0)
检查Timer
class:
使用
scheduledTimer(timeInterval:invocation:repeats:)
或scheduledTimer(timeInterval:target:selector:userInfo:repeats:)
课程 创建计时器的方法和在当前运行循环中安排它 默认模式。使用
init(timeInterval:invocation:repeats:)
或init(timeInterval:target:selector:userInfo:repeats:)
类方法 创建计时器对象而不在运行循环上安排它。 (后 创建它,您必须通过调用手动将计时器添加到运行循环 相应RunLoop对象的add(_:forMode:)
方法。)
因此,如果您想在主RunLoop中安排计时器,您可以这样写:
DispatchQueue.main.async {
Timer.scheduledTimer(
timeInterval: 0.1,
target: self,
selector: #selector(self.callee),
userInfo: nil,
repeats: false
)
}
不使用Timer
类,但这似乎更好:
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
self.callee()
}
(更新)明确指出RunLoop
类通常不被认为是线程安全的。您不应该使用旧代码(隐藏在编辑历史中),即使它似乎在某些有限的条件下有效。