Swift iOS应用:跳转ViewController后playAgainstComputer值自动置为false
问题排查与解决方案
1. 修复单例实现(核心问题)
你的GameSettings单例缺少私有初始化方法,外部可以随意创建新的GameSettings实例,这会导致不同控制器可能使用不同实例,出现变量值不统一的情况。修改单例类:
import Foundation class GameSettings { static let shared = GameSettings() private init() {} // 添加私有初始化,禁止外部创建新实例 var playAgainstComputer = false }
2. 统一控制器中访问单例的方式
确认两个控制器中所有操作playAgainstComputer的代码,都通过GameSettings.shared访问,而非控制器内部的同名局部变量:
- 修改
SecondViewController的按钮点击方法:
@IBAction func btnPlayNPC(_ sender: UIButton) { GameSettings.shared.playAgainstComputer = true // 明确操作单例变量 print("playAgainstComputer: \(GameSettings.shared.playAgainstComputer)") performSegue(withIdentifier: TO_GAME_SCREEN, sender: self) }
- 修改
GameViewController中读取变量的代码:
print("playAgainstComputer: \(GameSettings.shared.playAgainstComputer), currentPlayer: \(currentPlayer)") if GameSettings.shared.playAgainstComputer && currentPlayer == 2 { print("HERE") playAgainstNPC() makeComputerMove() }
如果控制器内部自己定义了var playAgainstComputer = false,会覆盖单例变量,导致修改和读取的不是同一个值,需删除此类局部变量。
3. 排查GameViewController的生命周期方法
检查GameViewController的viewDidLoad、viewWillAppear等方法中,是否存在意外重置playAgainstComputer的代码,比如:
override func viewDidLoad() { super.viewDidLoad() // 若存在以下代码需删除 // GameSettings.shared.playAgainstComputer = false }
4. 验证单例实例一致性
在两个控制器中分别打印单例的内存地址,确认是同一个实例:
- 在
SecondViewController的按钮方法中添加:
print("SecondVC Settings Instance: \(Unmanaged.passUnretained(GameSettings.shared).toOpaque())")
- 在
GameViewController的viewDidLoad中添加:
print("GameVC Settings Instance: \(Unmanaged.passUnretained(GameSettings.shared).toOpaque())")
如果地址不一致,说明仍存在多个GameSettings实例,回到步骤1和2排查。
内容的提问来源于stack exchange,提问作者AranAli
相关产品推荐
相关产品推荐

