我正在开发一个iOS应用程序,我正在尝试使用文本字段和按钮将整数提交到数组中,以便我可以使用“userdefaults”存储它。到目前为止,我有一个不同的文本字段添加输入到数组中的字符串并将其存储在用户默认值中。
@IBAction func workBtn(_ sender: Any)
{
let kidnum: Int = Int(enteredScore.text!)!
kidName.append(enteredName.text!)
kidScore.append(kidnum)
enteredName.text?.removeAll()
enteredScore.text?.removeAll()
}
@IBAction func finishBtn(_ sender: Any)
{
let userDefaults = UserDefaults.standard
userDefaults.set(kidName, forKey: "Pupil Name")
userDefaults.set(kidScore, forKey: "Pupil Score")
userDefaults.synchronize()
}
workBtn是我正在使用的添加按钮,我也尝试使用字符串,因为我实际上并不需要整数来计算,但只是为了显示分数但是我无法保存它,我正在通过它通过它显示在表视图控制器单元格上。感谢
我正在使用Xcode 9.1 Swift 4,谢谢。
编辑*** 在运行它后,我在标记为“线程1:致命错误:在解开可选值时意外发现nil”的行上的此函数中出现错误
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let userDefaults = UserDefaults.standard
var nameArray: [String] = userDefaults.object(forKey:"Pupil Name") as! [String]
//Error occurring on next line.
var scoreArray: [Int] = userDefaults.object(forKey: "Pupil Score") as! [Int]
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = "\(nameArray[indexPath.item]) -Score: \(scoreArray[indexPath.item])"
userDefaults.synchronize()
return cell
}
答案 0 :(得分:0)
您收到的错误意味着您正在某个您不期望的地方访问nil值。这很可能是通过强制解包您在代码中不断执行的某些值。尽量避免使用!
。在您的代码中,它可能是let kidnum: Int = Int(enteredScore.text!)!
之类的任何行,但也可能是某些字段缺少连接,并且被声明为@IBOutlet weak var enteredName: UITextField!
,遗憾的是这是默认的。
要调试此功能,您可能需要启用异常断点:在顶部Xcode左侧的导航器中,有一个断点图标(子弹)。选择它然后检查左下角并找到“+”按钮,按下它并选择“异常断点...”。然后只需点击即可。现在只要遇到像你这样的异常,你的执行就会停止。运行你的项目并找到行,对象是零,不应该是。然后解决您的问题。
但一般来说,尝试编写代码更像以下内容:
@IBOutlet private weak var scoreTextField: UITextField?
@IBOutlet private weak var nameTextField: UITextField?
private typealias NameScore = (name: String, score: Int)
private var dataArray: [NameScore] = [NameScore]()
override func viewDidLoad() {
super.viewDidLoad()
loadData()
}
@IBAction private func workPressed() {
let scoreValue: Int? = {
guard let string = scoreTextField?.text, let integer = Int(string) else {
return nil
}
return integer
}()
guard let score = scoreValue else {
print("Could not parse integer value") // TODO: Show alert view
return
}
guard let name = nameTextField?.text else {
print("Name was not provided") // TODO: Show alert view
return
}
dataArray.append((name: name, score: score))
// Clear text fields
scoreTextField?.text = nil
nameTextField?.text = nil
}
@IBAction private func finishPressed() {
saveData()
}
private let pupilNameKey: String = "name"
private let pupilScoreKey: String = "score"
private let pupilDataKey: String = "pupil_data"
private func saveData() {
// Let's convert data into something that makes more sense for safety
let dataToSave: [[String: Any]] = dataArray.map { object in
return [pupilNameKey: object.name,
pupilScoreKey: object.score]
}
UserDefaults.standard.set(dataToSave, forKey: pupilDataKey)
UserDefaults.standard.synchronize()
}
private func loadData() {
guard let savedData = UserDefaults.standard.value(forKey: pupilDataKey) as? [[String: Any]] else {
// No saved data or incorrect format
return
}
dataArray = savedData.flatMap { descriptor in
guard let name = descriptor[pupilNameKey] as? String, let score = descriptor[pupilScoreKey] as? Int else {
return nil // Could not parse this object
}
return (name: name, score: score)
}
}
表格视图:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dataArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
let dataObject = dataArray[indexPath.row]
cell.textLabel?.text = "\(dataObject.name) -Score: \(dataObject.score)"
return cell
}
我希望代码能说明如何避免强制解包以及如何打包数据。