简单的 MVC 计时器- Swift
Simple MVC Timer- Swift
我知道这是一个非常基本的问题,我正在尝试重构我的代码 atm 并且 运行 遇到了计时器问题。我想做的只是让一个简单的倒数计时器打印到控制台
这是我现在的代码片段
VC------
var seconds = 60
override func viewDidLoad() {
super.viewDidLoad()
self.modelInstance.gameTimerMethod(timeParam: self.seconds)
}
型号-----
func gameTimerMethod(timeParam : Int) {
gameTimer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(decreaseGameTimer(secondsParam:)), userInfo: timeParam, repeats: true)
print (timeParam)
}
func decreaseGameTimer(secondsParam: Int) {
var printNumber = secondsParam
printNumber -= 1
print (printNumber)
}
理想情况下,我希望它在控制台中执行的操作只是暂时从 60 开始以每秒一个数字的速度倒计时。虽然控制台以每秒一个数字的速度记录,但出于某种原因,它会重复记录数字 105553117734207,而不是 60 秒倒计时。
谢谢!
将printNumber
设为class变量,而不是放在方法中,这样定时器每次调用时都不会重置
同样在 gameTimerMethod
中,在调用计时器之前将 printNumber
设置为 timeParam
。
您的模型将类似于以下内容:
class YourModel {
var printNumber = 0
func gameTimerMethod(timeParam : Int) {
printNumber = timeParam
gameTimer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(decreaseGameTimer(), userInfo: nil, repeats: true)
print (timeParam)
}
func decreaseGameTimer() {
printNumber -= 1
print (printNumber)
}
}
传递给 decreaseGameTimer
的值是 Timer
实例。它有一个 属性 userInfo
引用传递给 Timer
构造函数的对象。
创建一个 class
来保存你的计数,然后将那个 class 的实例传递给计时器的 userInfo
:
class Model {
class TimerInfo {
var count: Int
// Pointer to function or closure to call when value changes
var callback: ((Int) -> Void)?
init(start: Int, callback: @escaping (Int) -> Void) {
count = start
self.callback = callback
}
deinit {
print("TimerInfo deinit")
}
}
@objc func decreaseGameTimer(_ timer: Timer) {
if let userInfo = timer.userInfo as? TimerInfo {
userInfo.count -= 1
// call callback with new value
userInfo.callback?(userInfo.count)
print(userInfo.count)
if userInfo.count == 0 {
print("done")
timer.invalidate()
}
}
}
func gameTimerMethod(timeParam: Int, callback: @escaping (Int) -> Void) {
_ = Timer.scheduledTimer(timeInterval: 1, target: self,
selector: #selector(decreaseGameTimer),
userInfo: TimerInfo(start: timeParam, callback: callback),
repeats: true)
}
}
那么你可以这样称呼它:
override func viewDidLoad() {
super.viewDidLoad()
// The closure that follows the gameTimerMethod call is using trailing
// closure syntax. It gets passed to gameTimerMethod as the second
// parameter named callback. This closure will get called every
// second until the timer finishes.
self.modelInstance.gameTimerMethod(timeParam: self.seconds) { value in
self.label.text = "\(value)"
}
// Just for fun, lets run a second one at the same time
self.modelInstance.gameTimerMethod(timeParam: 10) { value in
self.label2.text = "\(value)"
}
}
我知道这是一个非常基本的问题,我正在尝试重构我的代码 atm 并且 运行 遇到了计时器问题。我想做的只是让一个简单的倒数计时器打印到控制台
这是我现在的代码片段
VC------
var seconds = 60
override func viewDidLoad() {
super.viewDidLoad()
self.modelInstance.gameTimerMethod(timeParam: self.seconds)
}
型号-----
func gameTimerMethod(timeParam : Int) {
gameTimer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(decreaseGameTimer(secondsParam:)), userInfo: timeParam, repeats: true)
print (timeParam)
}
func decreaseGameTimer(secondsParam: Int) {
var printNumber = secondsParam
printNumber -= 1
print (printNumber)
}
理想情况下,我希望它在控制台中执行的操作只是暂时从 60 开始以每秒一个数字的速度倒计时。虽然控制台以每秒一个数字的速度记录,但出于某种原因,它会重复记录数字 105553117734207,而不是 60 秒倒计时。
谢谢!
将printNumber
设为class变量,而不是放在方法中,这样定时器每次调用时都不会重置
同样在 gameTimerMethod
中,在调用计时器之前将 printNumber
设置为 timeParam
。
您的模型将类似于以下内容:
class YourModel {
var printNumber = 0
func gameTimerMethod(timeParam : Int) {
printNumber = timeParam
gameTimer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(decreaseGameTimer(), userInfo: nil, repeats: true)
print (timeParam)
}
func decreaseGameTimer() {
printNumber -= 1
print (printNumber)
}
}
传递给 decreaseGameTimer
的值是 Timer
实例。它有一个 属性 userInfo
引用传递给 Timer
构造函数的对象。
创建一个 class
来保存你的计数,然后将那个 class 的实例传递给计时器的 userInfo
:
class Model {
class TimerInfo {
var count: Int
// Pointer to function or closure to call when value changes
var callback: ((Int) -> Void)?
init(start: Int, callback: @escaping (Int) -> Void) {
count = start
self.callback = callback
}
deinit {
print("TimerInfo deinit")
}
}
@objc func decreaseGameTimer(_ timer: Timer) {
if let userInfo = timer.userInfo as? TimerInfo {
userInfo.count -= 1
// call callback with new value
userInfo.callback?(userInfo.count)
print(userInfo.count)
if userInfo.count == 0 {
print("done")
timer.invalidate()
}
}
}
func gameTimerMethod(timeParam: Int, callback: @escaping (Int) -> Void) {
_ = Timer.scheduledTimer(timeInterval: 1, target: self,
selector: #selector(decreaseGameTimer),
userInfo: TimerInfo(start: timeParam, callback: callback),
repeats: true)
}
}
那么你可以这样称呼它:
override func viewDidLoad() {
super.viewDidLoad()
// The closure that follows the gameTimerMethod call is using trailing
// closure syntax. It gets passed to gameTimerMethod as the second
// parameter named callback. This closure will get called every
// second until the timer finishes.
self.modelInstance.gameTimerMethod(timeParam: self.seconds) { value in
self.label.text = "\(value)"
}
// Just for fun, lets run a second one at the same time
self.modelInstance.gameTimerMethod(timeParam: 10) { value in
self.label2.text = "\(value)"
}
}