所有单例函数都是两次调用。 “Prova”功能和计时器的选择器是两次调用。
class Timer {
static let sharedInstanceTimer = Timer()
var TimerCounter : NSTimer = NSTimer()
var Counter : Int = Int()
var TimerGameOver : Int = Int()
var TimerBonusMultipleCircle : Int = Int()
var TimerBonusBigCircle : Int = Int()
var TimerCounterInterval : NSTimeInterval = 1
init()
{
self.Counter = 60
self.TimerGameOver = 10
self.TimerBonusMultipleCircle = 5
self.TimerBonusBigCircle = 5
self.TimerCounterInterval = 1
}
func StartTimerCounter()
{
self.TimerCounter = NSTimer.scheduledTimerWithTimeInterval(self.TimerCounterInterval, target: Game.sharedInstanceGame, selector: #selector(Game.sharedInstanceGame.UpdateAllCounter), userInfo: nil, repeats: true)
}
func StopTimerCounter()
{
self.TimerCounter.invalidate()
}
}
并且...在另一个文件中,我呼叫StartTimerCounter()
import UIKit
class FirstViewController: UIViewController {
static let sharedInstanceFirstViewController = FirstViewController()
override func viewDidLoad() {
super.viewDidLoad()
let backButton = UIBarButtonItem(title: "00:00:60", style: UIBarButtonItemStyle.Plain, target: self, action: nil)
backButton.tintColor = UIColor.whiteColor()
navigationItem.leftBarButtonItem = backButton
Circle.sharedInstanceCircle.CreateCircle()
view.layer.addSublayer(Circle.sharedInstanceCircle.PrincipalCircle)
Game.sharedInstanceGame.Play()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func prefersStatusBarHidden() -> Bool {
return true
}
func ReturnToMenu()
{
navigationController?.popViewControllerAnimated(true)
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}
撇开我在下面建议修正的各种错误,我尝试了几种解决方案,但我找不到解决这个问题的方法。
答案 0 :(得分:2)
有几点想法:
您的sharedInstanceTimer
正在实例化Timer
(本身就是NSTimer
)。它不应该是NSTimer
的子类。
然后将TimerCounter
初始化为您从未使用的第二个计时器。
以上将实例化两个计时器。然后,每次调用它时,StartTimerCounter
都会实例化另一个NSTimer
。假设您只想要一个计时器,那么在开始一个计时器之前,您应该StartTimerCounter
使任何先前计时器无效。
我会打电话给这个班级TimerManager
,或类似的东西,以避免与Swift 3类型Timer
冲突。
方法名称应以小写字母开头,属性也应如此。根据Swift 3 API准则的精神,您可能也希望缩短方法名称。
另外,如果你要定义一个单例,我会声明一个private init()
初始值设定项,以防止其他类意外地实例化另一个TimerManager
对象。
所以,产生的结果如下:
class TimerManager {
static let shared = TimerManager()
private var timer: NSTimer? // this certainly should be private
// whether you make these private or not, or constants vs properties, is up to you
private var tounter : Int = 60
private var timerGameOver : Int = 10
private var timerBonusMultipleCircle : Int = 5
private var timerBonusBigCircle : Int = 5
private var timerCounterInterval : NSTimeInterval = 1
// make sure no one else accidentally instantiates another TimerManager
private init() {
}
/// Start timer.
func startTimer() {
stopTimer() // cancel prior timer, if any
timer = NSTimer.scheduledTimerWithTimeInterval(timerCounterInterval, target: Game.sharedInstanceGame, selector: #selector(Game.sharedInstanceGame.updateAllCounter), userInfo: nil, repeats: true)
Game.sharedInstanceGame.prova()
}
/// Stop timer.
func stopTimer() {
timer?.invalidate()
timer = nil
}
}
这里有一个不相关的,更深入的观察:我建议你保持计时器对象与Game
对象松散耦合。所以,我会从这个课程中删除所有与“游戏”相关的内容:
class TimerManager {
static let shared = TimerManager()
private var timer: NSTimer? // this certainly should be private
private var timerHandler: (() -> ())?
// whether you make these private or not, or constants vs properties, is up to you
private var timerCounterInterval: NSTimeInterval = 1
// make sure no one else accidentally instantiates another TimerManager
private init() {
}
/// Start timer.
///
/// - parameter timerHandler: The closure that will be called once per second.
func startTimer(timerHandler: () -> ()) {
stopTimer() // cancel prior timer, if any
self.timerHandler = timerHandler
timer = NSTimer.scheduledTimerWithTimeInterval(timerCounterInterval, target: self, selector: #selector(handleTimer(_:)), userInfo: nil, repeats: true)
}
@objc func handleTimer(timer: NSTimer) {
timerHandler?()
}
/// Stop timer.
func stopTimer() {
timer?.invalidate()
timerHandler = nil
timer = nil
}
}
然后,当Game
对象想要启动计时器时,它可能会执行:
TimerManager.shared.startTimer {
self.updateAllCounter()
}
prova()
现在,为了解决这个问题,你可能简化了你的计时器对象,也许这个TimerManager
对象需要更多的东西(正如你的代码片段中没有引用的所有其他属性所建议的那样) ,但希望这说明了基本思想:TimerManager
不应该涉及调用任何特定Game
方法等的业务。它应该只是提供一种机制,通过该机制,调用者可以简单地提供定时器应该定期调用的代码块。