Swift测验游戏Answer结构体重置逻辑问题求助
问题解决方案
核心问题分析
- 值类型拷贝导致数据不同步:
Quiz初始化时rounds = Answer.allAnswers是值拷贝,后续Answer.allAnswers更新后,Quiz内部的rounds仍是旧数组,不会自动同步。 - 方法调用错误:
Answer的resetAnswers是实例方法,但你调用的是Answer.resetAnswers()(类型方法),编译会报错,且无法修改静态数组。 - 无索引边界检查:
advanceRound未判断是否已到最后一轮,直接递增索引会导致越界。
分步修复代码
1. 修复Answer的重置方法为静态方法
将resetAnswers改为静态方法,确保能通过类型调用并更新静态数组:
import Foundation let roots = ["A", "B", "C", "D", "E", "F", "G"] let chordType = ["Major", "Minor"] func chooseChord() -> String { let randomRoot = roots.randomElement()! let randomType = chordType.randomElement()! let randomChord = randomRoot + randomType return randomChord } func genAnswer() -> (String, [String]) { var answers = [String]() while answers.count < 4 { let randChord = chooseChord() if !answers.contains(randChord) { answers.append(randChord) } } let correctAnswer = answers.randomElement()! return (correctAnswer, answers) } struct Answer { private(set) var correctAnswer: String private(set) var possibleAnswers: [String] init() { let answer = genAnswer() self.correctAnswer = answer.0 self.possibleAnswers = answer.1 } static var allAnswers: [Answer] = [ Answer(), Answer(), Answer(), Answer(), Answer() ] // 修改为静态方法 static func resetAnswers() { var newAnswers = [Answer]() for _ in 1...Answer.allAnswers.count { newAnswers.append(Answer()) } Answer.allAnswers = newAnswers } }
2. 更新Quiz的重置逻辑与边界检查
在reset方法中同步rounds数组,同时添加索引越界防护:
import Foundation class Quiz { private var rounds = Answer.allAnswers private var currentRoundIndex = 0 var currentRound: Answer { return rounds[currentRoundIndex] } var totalRounds: Int { rounds.count - 1 } // 新增:判断是否可进入下一轮 func canAdvance() -> Bool { currentRoundIndex < rounds.count - 1 } func advanceRound() { guard canAdvance() else { // 已到最后一轮,可在此添加测验结束逻辑 return } currentRoundIndex += 1 } func reset() { Answer.resetAnswers() // 同步最新的问题数组 rounds = Answer.allAnswers currentRoundIndex = 0 } }
3. 给QuizViewModel添加重置方法
供UI层调用以重置整个测验:
import Foundation class QuizViewModel: ObservableObject { @Published var game = Quiz() var correctAnswerText: String { game.currentRound.correctAnswer } func answerText() -> [String] { game.currentRound.possibleAnswers } var totalRounds: Int { return game.totalRounds } func advanceGame() { game.advanceRound() } // 新增:重置游戏方法 func resetGame() { game.reset() } }
关键优化说明
- 将
Answer的getter方法替换为private(set)属性,更符合Swift的面向值编程风格,减少冗余代码。 Quiz的canAdvance方法可用于UI层判断是否显示"下一题"按钮,避免无效操作。- 重置时手动同步
rounds数组,解决值类型拷贝导致的数据不同步问题。
内容的提问来源于stack exchange,提问作者Ness Earthbound
相关产品推荐
相关产品推荐

