gpt4 book ai didi

ios - 单例 SharedInstance 函数被调用两次

转载 作者:行者123 更新时间:2023-11-28 12:41:33 29 4
gpt4 key购买 nike

所有单例函数都是两次调用。“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.
}
*/

}

抛开我按照下面的建议更正的各种错误,我尝试了几种解决方案,但我找不到解决这个问题的方法。

最佳答案

几个想法:

  1. 您的 sharedInstanceTimer 正在实例化 Timer(它本身就是一个 NSTimer)。它不应该是 NSTimer 的子类。

  2. 然后您将 TimerCounter 初始化为您从未使用过的第二个计时器。

  3. 上面会实例化两个定时器。然后,您将拥有 StartTimerCounter,它会在您每次调用它时实例化另一个 NSTimer。假设您只需要一个计时器,您应该让 StartTimerCounter 在启动新计时器之前使任何先前的计时器无效。

  4. 我将此类称为 TimerManager 或类似名称,以避免与 Swift 3 类型 Timer 发生冲突。

  5. 方法名称应以小写字母开头,属性也应如此。本着 Swift 3 API 指南的精神,您可能也想缩短方法名称。

  6. 此外,如果您要定义一个单例,我会声明一个 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 方法等的业务。它应该简单地提供一种机制,调用者可以通过该机制简单地提供计时器应定期调用的代码块。

关于ios - 单例 SharedInstance 函数被调用两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39320817/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com