【发布时间】:2020-07-21 20:51:34
【问题描述】:
我是 Swift 编码的新手。我的目标是构建一个包含多个自定义类变量总和的变量。 说清楚的话:
我有一个名为“Entry”的自定义类,它具有 Double 变量“sum”,例如50.00。
我正在使用 ViewController 让用户使用文本字段输入创建一个新条目,尤其是新条目的总和。当按下相关按钮时,这个新的 entry 元素会被附加到一个 Entry 类型的数组中。
@IBAction func addEntry(_ sender: UIButton){
// take user input
let name = nameTextField.text ?? ""
let sum = Double(sumTextField.text!) ?? 0.0
let category = selectedCategory
// save user input in new entry
let newEntry = Entry(name: name, sum: sum, category: category)
entries.append(newEntry)
saveEntries()
os_log("Saved new entry successfully.", log: OSLog.default, type: .debug)
在另一个 ViewController 中,我想访问数组“条目”并构建所有条目元素的所有总和变量的总和,例如条目 1 的总和 + 条目 2 的总和 + 条目 3 的总和
我目前的编码尝试如下:
var entriesDatabase = [Entry]()
//extract sum of entries and build sumOfEntries
var sumArray = [Double]()
for entry in entriesDatabase {
sumArray.append(entry.sum)
}
sumOfEntries = sumArray.reduce(0, +)
第一个视图控制器中的条目数组通过使用 NSKeyedArchiver 保存,并在调用上述函数之前由第二个视图控制器中的 NSKeyedUnarchiver.unarchiveObject(withFile:) 加载(我知道,它已被弃用,但它适用于我目前的目的)。
我使用打印功能来隔离问题,据我所见,sumOfEntries 始终保持为 0.0,无论我创建了多少 Entry 元素(尽管它本身似乎有效)。 有谁知道我做错了什么?
编辑:对我来说,问题似乎是计算不起作用,而不是数据从一个视图传递到另一个视图。不知何故,数组总是空的。数据的传递通过将其持久保存在驱动器上,然后使用 NSKeyedArchiver 函数加载它来工作。为清楚起见,请参见以下代码:
/MARK: calculate and display balance
func calculate(){
//load data from user defaults
recurringCalculationValue = UserDefaults.standard.value(forKey: "recurringExpenses") ?? 0.0
monthlyIncomeCalculationValue = UserDefaults.standard.value(forKey: "monthlyIncome") ?? 0.0
//extract sum of entries and build sumOfEntries
var sumArray = [Double]()
for entry in entriesDatabase {
sumArray.append(entry.sum)
}
sumOfEntries = sumArray.reduce(0, +)
//cast the user defaults into Double
let mICV = monthlyIncomeCalculationValue as! Double
let rCV = recurringCalculationValue as! Double
//convert the Strings to Double! and calculate balance
balance = Double(mICV) - Double(rCV) - sumOfEntries
//display balance in sumLabel
sumLabel.text = "\(balance)"
//debugging
print("balance = \(balance)")
print("sumOfEntries = \(sumOfEntries)")
print("monthlyIncomeCalculationValue = \(monthlyIncomeCalculationValue)")
print("recurringCalculationValue = \(recurringCalculationValue)")
print("UserDefault monthlyIncome = \(String(describing: UserDefaults.standard.value(forKey: "monthlyIncome")))")
print("UserDefault recurringExpenses = \(String(describing: UserDefaults.standard.value(forKey: "recurringExpenses")))")
}
//this function is called when the ViewController is opened
@IBAction func unwindToThisViewController(segue: UIStoryboardSegue) {
//Load saved entries into entries array if entries were saved
let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
let url = NSURL(fileURLWithPath: path)
if let pathComponent = url.appendingPathComponent("entries") {
let filePath = pathComponent.path
let fileManager = FileManager.default
if fileManager.fileExists(atPath: filePath) {
print("File available.")
entriesDatabase = loadEntries()!
print("Database loaded.")
} else {
print("File not available.")
}
} else {
print("File path not available.")
}
calculate()
}
private func loadEntries() -> [Entry]? {
return NSKeyedUnarchiver.unarchiveObject(withFile: Entry.ArchiveURL.path) as? [Entry]
}
我希望这能让我的问题更清楚,再次感谢!
【问题讨论】:
-
您不应该使用 UserDefaults 在视图控制器之间传递值,而是参见 stackoverflow.com/questions/5210535/…
-
首先,感谢您的回复。可能我的描述不够清楚。我不使用 UserDefaults 来传递数据,而是使用带有永久安全文件的 NSKeyedArchiver。此外,您所指的线程确实 - 至少在我的理解中 - 不能解决我遇到的问题。我成功传递了数据,但是Mu计算不起作用。数组保持为空。然而,也许我只是不明白你在说什么。你能详细说明一下吗? :)
-
@JoakimDanielson 请查看有问题的更新代码。
-
我看到您的代码有一些可以改进的地方,但是如果您声称
entriesDatabase包含对象,那么您的代码会正确计算总和。 -
@JoakimDanielson 嗯,好的。好吧,我想我只需要留在原地,弄清楚将数据传递给条目数据库时可能出现的问题。感谢您的帮助!