如何在swift中使用dispatch_sync?

时间:2016-07-26 23:18:48

标签: swift firebase grand-central-dispatch firebase-realtime-database

这是我第一次使用堆栈溢出。我试图让我的程序在继续之前等待查询任务完成,但我从来没有让它正常行为。我输入了print语句进行调试。第二次和第三次打印始终在第一次打印之前。我想我不太了解dispatch_sync。任何帮助将不胜感激!

        let concurrentQueue = dispatch_queue_create(
            "com.x.TinderClone.queue", DISPATCH_QUEUE_CONCURRENT)

        dispatch_sync(concurrentQueue) {
            usersRef.queryOrderedByChild("gender").queryEqualToValue(userInterestedIn).observeSingleEventOfType(.Value, withBlock: {snapshot in
                for child in snapshot.children {
                    let uid = child.key!!
                    let gender = child.value!!["gender"] as! String
                    let id = child.value!!["id"] as! String
                    let interestedInWomen = child.value!!["interestedInWomen"] as! Bool
                    let name = child.value!!["name"] as! String

                    let potentialMatch = User(uid: uid, gender: gender, id: id, interestedInWomen: interestedInWomen, name: name)
                    listOfPotentialMatches.append(potentialMatch) //add the user struct to the array
                }

                print("First") // First print

                // ...
                }) { (error) in
                    print(error.localizedDescription)
            }

            print("Second") // Second Print
        }

        print("Third") //Third print

3 个答案:

答案 0 :(得分:1)

observeSingleEventOfType(:withBlock:)需要一个块,其中包含您编写的大部分代码,包括print("First")块是异步执行的。

换句话说,您的dispatch_sync代码调用异步代码。立即dispatch_sync代码会立即运行,但反过来调用的异步代码则不会。

您必须假设传递给observeSingleEventOfType(:withBlock:)的块可能无序执行并相应地进行设计。

答案 1 :(得分:0)

正如您所发现的那样,dispatch_sync并没有真正帮助您。问题是,您提供给observeSingleEventOfType的块作为参数传递 - 不是同步执行 - 并且只要Firebase认为合适(可能是在事件发生时)就会执行。

"Second"之后进行"Third""First"打印的最简单方法是将放入块中,或将它们放入函数中你在街区尽头打电话。

答案 2 :(得分:0)

之前我见过同样的问题。最近我找到了一种解决方法,使用Timers来“等待”从Firebase获取数据。以下是一段摘录,您可以在观察事件后尝试适应您的操作:

var timer:NSTimer?

private func attemptReloadOfTable(){         self.timer?.invalidate()

    self.timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: #selector(self.handleReloadTable), userInfo: nil, repeats: false)
}