一尘不染

Swift可以从异步Void返回块返回值吗?

swift

我想创建一个函数来检查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是第三方Firebase提供的API。它定义为return Void

  • (void)observeSingleEventOfType:(FEventType)eventType
    withBlock:(void(^)(FDataSnapshot * snapshot))块

错误: 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
}

不知何故,它在那里冻结了。我知道这种方法现在可能不合时宜。但是请帮忙。


阅读 260

收藏
2020-07-07

共1个答案

一尘不染

您应该自己使用异步完成处理程序:

class func checkIfUserExists(uid: String, completionHandler: (Bool) -> ()) {
    userRef.childByAppendingPath(uid).observeSingleEventOfType(.Value) { snapShot in
        if snapShot.value is NSNull {
            completionHandler(false)
        } else {
            completionHandler(true)
        }
    }
}

然后可以这样调用:

MyClass.checkIfUserExists(uid) { success in
    // use success here
}

// but not here

在修改后的问题中,您演示了使用调度组使此异步方法同步运行。(信号灯通常也用于相同的目的。)

两个问题:

  1. 如果他们将完成处理程序分派回主队列,这将导致死锁(在许多情况下,库将这样做以简化我们的工作),因为您恰巧阻塞了他们试图使用的同一线程。我不知道这是否是他们在这里所做的,但很有可能。

如果要确认这一点,请临时删除调度组,然后检查NSThread.isMainThread并查看它是否在主线程中运行。

  1. 无论如何,您永远都不应阻塞主线程。他们提供了一个异步接口是有充分的理由的,因此在调用它时应该使用异步模式。不要对抗异步模式,而应该拥抱它们。
2020-07-07