Swift 如何使用异步函数之外的值?
最初的函数应该是这样的:Swift 如何使用异步函数之外的值?,swift,function,asynchronous,Swift,Function,Asynchronous,最初的函数应该是这样的: func retrieveMonthlySpent(month:String, year:String) -> Double { FirebaseFunctions().retrieve(from: .expense, username: self.username as! String, returning: Expenses.self) { (expenses) in self.monthlyExpenses = expenses
func retrieveMonthlySpent(month:String, year:String) -> Double {
FirebaseFunctions().retrieve(from: .expense, username: self.username as! String, returning: Expenses.self) { (expenses) in
self.monthlyExpenses = expenses
}
var sum:Double = 0
for expense in self.monthlyExpenses{
if expense.modificationDate.convertToMonth() == month && expense.expense && expense.modificationDate.convertToYear() == year {
sum += expense.convertedAmount
}
}
return sum
}
但由于Swift中同步功能的工作方式,每月费用值不会更新。因此,我尝试更改代码,以便将尽可能多的代码放入异步函数本身,结果如下所示:
func retrieveMonthlySpent(month:String, year:String) -> Double{
FirebaseFunctions().retrieve(from: .expense, username: self.username as! String, returning: Expenses.self) { (expenses) in
self.monthlyExpenses = expenses
var sum:Double = 0
for expense in self.monthlyExpenses{
if expense.modificationDate.convertToMonth() == month && expense.expense && expense.modificationDate.convertToYear() == year{
sum += expense.convertedAmount
}
}
}
return sum
}
但问题是现在sum的值是0,因为我在这个异步函数之外使用了一个变量。我已经看到这个问题在多个问题上被提出,但我在任何地方都找不到答案。此问题的解决方案是什么?如果调用异步API,则必须使用完成处理程序:
func retrieveMonthlySpent(month:String, year:String, success: @escaping (Double) -> Void) {
FirebaseFunctions().retrieve(from: .expense, username: self.username as! String, returning: Expenses.self) { (expenses) in
self.monthlyExpenses = expenses
var sum:Double = 0
for expense in self.monthlyExpenses{
if expense.modificationDate.convertToMonth() == month && expense.expense && expense.modificationDate.convertToYear() == year{
sum += expense.convertedAmount
}
}
success(sum)
}
}
您可以从当前控制器使用此方法,如下所示:
self.retrieveMonthlySpent(month: "", year: "") { (sum) in
print(sum)
}
Xviewcontroller().retrieveMonthlySpent(month: "", year: "") { (sum) in
total = sum
}
或者从其他ViewController,您可以这样使用:
self.retrieveMonthlySpent(month: "", year: "") { (sum) in
print(sum)
}
Xviewcontroller().retrieveMonthlySpent(month: "", year: "") { (sum) in
total = sum
}
为了更好地重用代码,您需要将此方法放在superviewcontroller或任何公共类中。在获取数据时,将完成处理程序用作触发器更新UI 具有完成处理程序的设置函数:
func retrieveMonthlySpent(month:String, year:String, completion: ((Double) -> Void)? = nil) {
FirebaseFunctions().retrieve(from: .expense, username: self.username as! String, returning: Expenses.self) { (expenses) in
self.monthlyExpenses = expenses
var sum = 0.0
for expense in self.monthlyExpenses {
if expense.modificationDate.convertToMonth() == month && expense.expense && expense.modificationDate.convertToYear() == year {
sum += expense.convertedAmount
}
}
completion(sum)
}
}
在viewController中使用它,例如:
func retrieveMonthlySpent(month:"05", year:"1996") { result in
self.sumLabel.text = result
}
就像塔诺斯折断手指的方式一样简单:好的,但是在第二个视图控制器中,我会不会遇到一个问题,我不能在完成处理程序之外使用变量total?你不能在block man之外使用这个变量