如何在 swift 中使用 dispatch_sync?

How do I use dispatch_sync in swift?

这是我第一次使用堆栈溢出。我试图让我的程序在继续之前等待查询任务完成,但我从来没有让它正确运行。我输入了用于调试的打印语句。第二和第三次打印总是在第一次打印之前。我想我不是很了解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

observeSingleEventOfType(:withBlock:)取一个块,里面包含了你写的大部分代码,包括print("First")那个块是异步执行的。

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

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

如您所见,dispatch_sync 并不能真正帮助您。问题是您提供给 observeSingleEventOfType 的块作为参数传递——不是同步执行的——并且会在 Firebase 认为合适的时候执行(大概是在事件发生时)。

使 "Second""Third""First" 之后打印的最简单方法是将它们 放在 块中,或者将它们放在您在块末尾调用的函数中。

我以前也遇到过同样的问题。最近,我发现了一种解决方法,即使用定时器 "wait" 来让您的数据从 Firebase 中提取。这是一个片段,您可以尝试在观察事件后适应您的操作:

可变定时器:NSTimer?

私有函数 attemptReloadOfTable() { self.timer?.invalidate()

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