Swift return 值可以来自异步 Void-returning 块吗?
Can Swift return value from an async Void-returning block?
我想创建一个函数来检查 user_id 是否已经在我的数据库中。
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
是由第 3 方 Firebase 提供的 API。它被定义为 return Void
。
- (void)observeSingleEventOfType:(FEventType)eventType withBlock:(void ( ^ ) ( FDataSnapshot *snapshot ))block
错误:Type 'Void' does not conform to protocol 'BooleanLiteralConvertible'
感谢任何形式的帮助。
更新
我正在尝试不同的方式:
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
}
不知怎的,它只是冻结在那里。我知道这种方法现在可能离题了。但请帮忙。
您应该自己使用异步(即转义)完成处理程序:
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
在您修改后的问题中,您演示了使用调度组来使此异步方法同步运行。 (信号量也经常用于相同的目的。)
两期:
如果他们将完成处理程序分派回主队列(在许多情况下,图书馆会这样做是为了简化我们的生活),这将会死锁,因为你恰好阻塞了同样的事情他们试图使用的线程。我不知道这是否是他们在这里所做的,但很有可能。
如果你想确认这一点,暂时删除调度组,然后检查NSThread.isMainThread
,看看它是否在主线程中运行。
无论如何,你永远不应该阻塞主线程。他们有充分的理由提供异步接口,因此您应该在调用它时使用异步模式。不要对抗异步模式,而是拥抱它们。
我想创建一个函数来检查 user_id 是否已经在我的数据库中。
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
是由第 3 方 Firebase 提供的 API。它被定义为 return Void
。
- (void)observeSingleEventOfType:(FEventType)eventType withBlock:(void ( ^ ) ( FDataSnapshot *snapshot ))block
错误:Type 'Void' does not conform to protocol 'BooleanLiteralConvertible'
感谢任何形式的帮助。
更新
我正在尝试不同的方式:
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
}
不知怎的,它只是冻结在那里。我知道这种方法现在可能离题了。但请帮忙。
您应该自己使用异步(即转义)完成处理程序:
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
在您修改后的问题中,您演示了使用调度组来使此异步方法同步运行。 (信号量也经常用于相同的目的。)
两期:
如果他们将完成处理程序分派回主队列(在许多情况下,图书馆会这样做是为了简化我们的生活),这将会死锁,因为你恰好阻塞了同样的事情他们试图使用的线程。我不知道这是否是他们在这里所做的,但很有可能。
如果你想确认这一点,暂时删除调度组,然后检查
NSThread.isMainThread
,看看它是否在主线程中运行。无论如何,你永远不应该阻塞主线程。他们有充分的理由提供异步接口,因此您应该在调用它时使用异步模式。不要对抗异步模式,而是拥抱它们。