如何创建最终会返回一些数据的函数,调用者必须等待

时间:2016-01-20 20:04:59

标签: ios swift function firebase

这实际上是一种Swift语言类型的问题

我正在使用Firebase来读/写数据

我想在swift中设计一个最终会返回 的例程。调用者必须等待例程完成,因此它实际上不是异步的后台调用。理想情况下,呼叫者也应该能够:

  1. 确定成功或错误返回并处理返回值

  2. 如果调用函数花费的时间过长,则等待超时

  3. 在功能内部,暂停只是Firebase的一个事件。例如:

    func eventuallyReturnFirebase() {
    
    //some stuff
    
    someObj.observeEventType(.ChildAdded, withBlock: {
                snapshot in
                print("\(snapshot.key) -> \(snapshot.value)")
                if (snapshot.key == "foo") {
                    // we found value for foo
                }
                if (snapshot.key == "bar") {
                    // we found value for bar
                }
            })
    //now we can return foo and bar back to caller or some error if we did not
    }
    

    有人可以突出显示Swift语言在设计此类功能方面提供的内容以及如何使用调用者?希望也能解决2个理想条件

2 个答案:

答案 0 :(得分:2)

如果需要围绕异步调用编写同步包装器 - 可以使用信号量。

即。你可以写这样的东西(我省略某些类似于类型信息的东西,所以它有点类似swift的伪代码,但这应该足以得到这个想法):

func eventuallyReturnFirebase() {

let semaphore = dispatch_semaphore_create(0) //creating a "closed" semaphore
var foo, bar //variables that will hold your return values

someObj.observeEventType(.ChildAdded, withBlock: {
            snapshot in
            print("\(snapshot.key) -> \(snapshot.value)")
            if (snapshot.key == "foo") {
                // we found value for foo
            }
            if (snapshot.key == "bar") {
                // we found value for bar
            }

            //setting values for foo and bar 
            foo = ...  
            bar = ...

            dispatch_semaphore_signal(semaphore) // incrementing semaphore counter
        })

let timeout = dispatch_time(DISPATCH_TIME_NOW, DefaultTimeoutLengthInNanoSeconds)
if dispatch_semaphore_wait(semaphore, timeout) != 0 { // waiting until semaphore conter becomes greater than 0
    print("timed out")
}

return foo, bar
}

答案 1 :(得分:1)

我建议将NSCondition视为获得所需结果的方法。

被调用的例程启动一个计时器,启动一个异步进程,然后在返回之前等待一个条件。条件被指示为异步进程的最后一个操作或通过触发计时器。

一旦信号允许例程继续,它就会决定它是因为时间而终止还是有东西要归还。