当您在 Swift 中有嵌套函数时,如何将布尔值返回给外部函数?
Posted
技术标签:
【中文标题】当您在 Swift 中有嵌套函数时,如何将布尔值返回给外部函数?【英文标题】:How to return a bool to the outside function when you have nested functions in Swift? 【发布时间】:2017-03-29 23:42:13 【问题描述】:所以我有一个函数,它有一个连接到 Firebase 数据库的内部函数。该函数返回一个布尔值,但我需要根据 Firebase 数据库中的内容返回 true 或 false。所以基本上我需要在 Firebase 函数内部返回 true 或 false 问题是当我实际上试图返回外部函数时,它认为我正在尝试返回 Firebase 函数,一个简单的例子就是这样
func someOtherFunc(name: String, lastname: String)
func someFunc(name: String, lastname: String) -> bool
someOtherFunc(name: name, lastname: lastname)
if name == "George"
return true
else
return false // will not work because some other func does not return a value
这是我需要修复的代码,它比上面的函数稍微复杂一点,因为内部 Firebase 函数是异步运行的(在后台),所以函数内的所有代码都需要同步运行才能返回正确的值
这是我的功能
func takeAwayMoney(_ howMuch: String) -> Bool
if let notMuch = Int(howMuch)
let userID = FIRAuth.auth()?.currentUser?.uid
datRef.child("User").child(userID!).observeSingleEvent(of: .value, with: (snapshot) in
// Get user value
let value = snapshot.value as? NSDictionary
let money = value?["money"] as? String ?? ""
//convert money to int
if let conMoney = Int(money)
var conMoreMoney = conMoney
if conMoreMoney < notMuch
print(" sorry you don't have enough money")
return false
else
conMoreMoney -= notMuch
let values = ["money": String(conMoreMoney)]
//update the users money
self.datRef.child("User").child(userID!).updateChildValues(values)
return true //doesn't work because of example above
// ...
) (error) in
print(error.localizedDescription)
此代码无法编译,因为主函数没有返回值。
我知道解决这个问题的真正困难的方法是在函数顶部初始化值,这将是用户的钱,然后在调度它几秒钟后检查它,然后你可以返回值,但是我知道肯定有其他方法,因为这种方法会导致很多问题。
【问题讨论】:
Can Swift return value from an async Void-returning block?的可能重复 Firebase 是异步的,尝试返回值(即使有额外的完成句柄、线程等)确实会使事情变得过于复杂,并且需要大量额外的代码。简单的解决方案是重新考虑为什么要返回 true 或 false,以及返回的值如何影响其余代码。在这种情况下,代码会检查用户有多少钱并据此采取行动——返回的值没有被使用。更新 UI,然后仍处于关闭状态,如果有则继续下一步。这将提供流畅的用户体验。 【参考方案1】:根本原因是takeAwayMoney
是同步的,但它使用的是异步的observeSingleEvent
。
解决这个问题的“正确”方法是让 takeAwayMoney
返回 Void,但采用一个完成函数,它会异步为您提供 bool,如下所示:
func takeAwayMoney(_ howMuch: String, completion: @escaping (Bool)->()) -> Void
/// When you want to "return" the bool, call the completion. e.g.:
// ...
if conMoreMoney < notMuch
print(" sorry you don't have enough money")
completion(false)
return // if you want to stop processing
// ...
如果您无法做到这一点,那么 takeMoney 需要等待完成,然后您使用信号量让它们相互通信。你不只是等待几秒钟。举个例子:
Semaphores to run asynchronous method synchronously
【讨论】:
这种问题已经被问过很多很多次了。最好作为一个骗子关闭而不是发布另一个答案。 好的,但是当我调用函数时,这会带来另一个问题,类似于 takeAwayMoney("20", completion: (result: Bool) in guard let returnedResult = result else return //这部分是与函数同步运行还是与主线程同步运行?)我需要知道将依赖于完成时返回的布尔值的代码放在哪里。 @LouFranco 如果您最终需要使其同步,那么您需要查看重复的问题或我发布的问题。 被observeSingleEvent响应的线程调用。如果您需要它作为主线程,请使用 dispatch_async 到主线程来执行此操作。一切都将是异步的。 你能告诉我如何使用 firebase 同步运行代码以上是关于当您在 Swift 中有嵌套函数时,如何将布尔值返回给外部函数?的主要内容,如果未能解决你的问题,请参考以下文章
当您在 postgres-XL 中有多个协调器时,您是不是有任何浮动 ip 重定向到一个协调器?
当您在情节提要中“因特性而异”时,为啥此自动布局扩展会失败?