Can Swift return value from an async Void-returning block?(Swift 可以从异步 Void 返回块返回值吗?)
问题描述
我想创建一个函数来检查 user_id 是否已经在我的数据库中.
I want to create a function to check if user_id is already in my database.
class func checkIfUserExsits(uid:String) -> Bool {
userRef.childByAppendingPath(uid).observeSingleEventOfType(.Value, withBlock: { (snapShot: FDataSnapshot!) -> Void in
if snapShot.value is NSNull {
return false
} else {
return true
}
})
}
但是,observeSingleEventOfType
是由 3rd 方 Firebase 提供的 API.它被定义为返回 Void
.
However, observeSingleEventOfType
is a API provided by 3rd party Firebase. It is defined to return Void
.
- (void)observeSingleEventOfType:(FEventType)eventType withBlock:(void ( ^ ) ( FDataSnapshot *snapshot ))block
错误:类型Void"不符合协议BooleanLiteralConvertible"
感谢任何形式的帮助.
更新
我正在尝试不同的方式:
I am trying a different way:
class func checkIfExist(uid: String) -> Bool {
var answer:Bool = false
var text:String = "not yet completed"
let queue = dispatch_group_create()
dispatch_group_enter(queue)
userRef.childByAppendingPath(uid).observeSingleEventOfType(.Value, withBlock: { (snapShot: FDataSnapshot!) -> Void in
if snapShot.value is NSNull {
text = "This is a new user"
answer = false
dispatch_group_leave(queue)
} else {
text = "Found the user in Firebase"
answer = true
dispatch_group_leave(queue)
}
})
dispatch_group_wait(queue, DISPATCH_TIME_FOREVER)
println(text)
return answer
}
不知何故,它只是冻结在那里.我知道这种方法现在可能离题了.但请帮忙.
Somehow it just freeze there. I know this approach could be off-topic now. But please help.
推荐答案
您应该自己使用异步(即转义)完成处理程序:
You should employ asynchronous (ie, escaping) completion handler yourself:
class func checkIfUserExists(uid: String, completion: @escaping (Bool) -> Void) {
userRef.childByAppendingPath(uid).observeSingleEventOfType(.Value) { snapShot in
if snapShot.value is NSNull {
completion(false)
} else {
completion(true)
}
}
}
你可以这样称呼它:
MyClass.checkIfUserExists(uid) { success in
// use success here
}
// but not here
在您修改后的问题中,您演示了如何使用调度组来使此异步方法同步运行.(信号量也经常用于相同的目的.)
In your revised question, you demonstrate the use of dispatch groups to make this asynchronous method behave synchronously. (Semaphores are also often used to the same ends.)
两个问题:
如果他们将完成处理程序分派回主队列,这将导致死锁(在许多情况下,库会这样做以简化我们的生活),因为你碰巧阻塞了它们所在的同一个线程试图使用.我不知道这是否是他们在这里所做的,但很有可能.
This will deadlock if they dispatch their completion handler back to the main queue (and in many cases, libraries will do this to simplify life for us), because you're coincidentally blocking the very same thread they're trying to use. I don't know if that's what they've done here, but is likely.
如果您想确认这一点,请暂时删除调度组,然后检查 NSThread.isMainThread
并查看它是否在主线程中运行.
If you want to confirm this, temporarily remove dispatch group and then examine NSThread.isMainThread
and see if it's running in main thread or not.
无论如何,你永远不应该阻塞主线程.他们提供了一个异步接口是有充分理由的,所以在调用它时应该使用异步模式.不要与异步模式抗争,而是拥抱它们.
You never should block the main thread, anyway. They provided an asynchronous interface for good reason, so you should use asynchronous patterns when calling it. Don't fight the asynchronous patterns, but rather embrace them.
这篇关于Swift 可以从异步 Void 返回块返回值吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:Swift 可以从异步 Void 返回块返回值吗?
基础教程推荐
- 在 gmail 中为 ios 应用程序检索朋友的朋友 2022-01-01
- android 应用程序已发布,但在 google play 中找不到 2022-01-01
- 如何在 iPhone 上显示来自 API 的 HTML 文本? 2022-01-01
- 如何在 UIImageView 中异步加载图像? 2022-01-01
- UIWebView 委托方法 shouldStartLoadWithRequest:在 WKWebView 中等效? 2022-01-01
- 如何在没有IB的情况下将2个按钮添加到右侧的UINavigationbar? 2022-01-01
- Kivy Buildozer 无法构建 apk,命令失败:./distribute.sh -m “kivy"d 2022-01-01
- 如何让对象对 Cocos2D 中的触摸做出反应? 2022-01-01
- Android:对话框关闭而不调用关闭 2022-01-01
- 当从同一个组件调用时,两个 IBAction 触发的顺序是什么? 2022-01-01