Ios Swift Firebase多线程问题
我试图在一个函数中运行几个for循环,该函数应该返回一个字符串数组 我遇到的问题是在运行下一个for循环之前获得正确的结果…然后在需要返回字符串数组以完成函数之前再次返回该结果 在第一种情况下,我有一个从Firebase获取数据的for循环。我能够使用一个调度组来获取要打印的值,但是在这之后的另一个循环中,我在上一个任务中使用调度组时遇到了问题 如果使用正确的值执行,代码都可以完美工作,但我不确定如何处理线程。非常感谢您的帮助Ios Swift Firebase多线程问题,ios,swift,multithreading,firebase,grand-central-dispatch,Ios,Swift,Multithreading,Firebase,Grand Central Dispatch,我试图在一个函数中运行几个for循环,该函数应该返回一个字符串数组 我遇到的问题是在运行下一个for循环之前获得正确的结果…然后在需要返回字符串数组以完成函数之前再次返回该结果 在第一种情况下,我有一个从Firebase获取数据的for循环。我能够使用一个调度组来获取要打印的值,但是在这之后的另一个循环中,我在上一个任务中使用调度组时遇到了问题 如果使用正确的值执行,代码都可以完美工作,但我不确定如何处理线程。非常感谢您的帮助 func findTopSpots() -> [String]
func findTopSpots() -> [String] {
var topFive = [String]()
var locationRatingDictionary = [String:Double]()
let myGroup = DispatchGroup()
let locationsArray = ["wyoming", "kansas", "arkansas", "florida", "california"]
// Use the days to find the most common month
let calendar = NSCalendar.current
var monthArray = [String]()
var date = self.departureDate!
let endDate = self.returnDate!
// Formatter for printing the month name
let fmt = DateFormatter()
fmt.dateFormat = "MMMM"
// Add each days month to an array
while date <= endDate {
date = calendar.date(byAdding: .day, value: 1, to: date)!
monthArray.append(fmt.string(from: date))
}
// Return the primary month from function
let primaryMonth = findMostCommonMonthInArray(array: monthArray).lowercased()
// Create a dictionary of location:rating for the primary month
for doc in locationsArray {
self.db.collection("locations").document(doc).collection("historic").document(primaryMonth).getDocument { (document, err) in
if let document = document, document.exists {
let rating = document["rating"] as? Double
locationRatingDictionary[doc] = rating
} else {
print("Document does not exist")
}
}
}
//---- THE CODE BELOW WILL NOT PRINT WITH ANY VALUES ----//
print(locationRatingDictionary)
// Sort the tuple array by rating
let locationRatingTupleArray = locationRatingDictionary.sorted{ $0.value > $1.value }
// Return 5 results
for (location,rating) in locationRatingTupleArray.prefix(5) {
print(location,rating)
topFive.append(location)
}
print("top five are \(topFive)")
return topFive
}
func findTopSpots()->[字符串]{
变量topFive=[String]()
var locationRatingDictionary=[String:Double]()
让myGroup=DispatchGroup()
let location sarray=[“怀俄明州”、“堪萨斯州”、“阿肯色州”、“佛罗里达州”、“加利福尼亚州”]
//使用天查找最常见的月份
让日历=NSCalendar.current
var monthArray=[String]()
var date=self.departureDate!
让endDate=self.returnDate!
//用于打印月份名称的格式化程序
设fmt=DateFormatter()
fmt.dateFormat=“MMMM”
//将每个月的天数添加到数组中
而日期为$1.0}
//返回5个结果
用于locationRatingTupleArray.前缀(5)中的(位置、等级){
打印(位置、等级)
topFive.append(位置)
}
打印(“前五名是\(前五名)”)
返回前五名
}
您的代码是异步的,最快的方法是完成dispatchGroup
//
func findTopSpots(完成:@escaping(arr:[string])->void){
让dispatchGroup=dispatchGroup()
变量topFive=[String]()
var locationRatingDictionary=[String:Double]()
let location sarray=[“怀俄明州”、“堪萨斯州”、“阿肯色州”、“佛罗里达州”、“加利福尼亚州”]
//使用天查找最常见的月份
让日历=NSCalendar.current
var monthArray=[String]()
var date=self.departureDate!
让endDate=self.returnDate!
//用于打印月份名称的格式化程序
设fmt=DateFormatter()
fmt.dateFormat=“MMMM”
//将每个月的天数添加到数组中
而日期为$1.0}
//返回5个结果
用于locationRatingTupleArray.前缀(5)中的(位置、等级){
打印(位置、等级)
topFive.append(位置)
}
打印(“前五名是\(前五名)”)
完成(前五名)
}
}
这里的问题是firebase异步返回查询结果,而不是等待它返回
我可以看到您已经实例化了DispatchGroup
,但还没有使用它。让我们试着用它来解决你的问题。此外,您还需要更改方法签名以进行闭包。这避免了阻塞线程以返回函数输出
func findTopSpots(completionHandler:([String])->Void) {
var topFive = [String]()
var locationRatingDictionary = [String:Double]()
let myGroup = DispatchGroup()
let locationsArray = ["wyoming", "kansas", "arkansas", "florida", "california"]
// Use the days to find the most common month
let calendar = NSCalendar.current
var monthArray = [String]()
var date = self.departureDate!
let endDate = self.returnDate!
// Formatter for printing the month name
let fmt = DateFormatter()
fmt.dateFormat = "MMMM"
// Add each days month to an array
while date <= endDate {
date = calendar.date(byAdding: .day, value: 1, to: date)!
monthArray.append(fmt.string(from: date))
}
// Return the primary month from function
let primaryMonth = findMostCommonMonthInArray(array: monthArray).lowercased()
// Create a dictionary of location:rating for the primary month
for doc in locationsArray {
myGroup.enter() self.db.collection("locations").document(doc).collection("historic").document(primaryMonth).getDocument { (document, err) in
if let document = document, document.exists {
let rating = document["rating"] as? Double
locationRatingDictionary[doc] = rating
} else {
print("Document does not exist")
}
myGroup.leave()
}
}
myGroup.notify(queue:.main) {
//---- THE CODE BELOW WILL NOT PRINT WITH ANY VALUES ----//
print(locationRatingDictionary)
// Sort the tuple array by rating
let locationRatingTupleArray = locationRatingDictionary.sorted{ $0.value > $1.value }
// Return 5 results
for (location,rating) in locationRatingTupleArray.prefix(5) {
print(location,rating)
topFive.append(location)
}
print("top five are \(topFive)")
completionHandler(topFive)
}
}
func findTopSpots(completionHandler:([String])->Void){
变量topFive=[String]()
var locationRatingDictionary=[String:Double]()
让myGroup=DispatchGroup()
let location sarray=[“怀俄明州”、“堪萨斯州”、“阿肯色州”、“佛罗里达州”、“加利福尼亚州”]
//使用天查找最常见的月份
让日历=NSCalendar.current
var monthArray=[String]()
var date=self.departureDate!
让endDate=self.returnDate!
//用于打印月份名称的格式化程序
设fmt=DateFormatter()
fmt.dateFormat=“MMMM”
//将每个月的天数添加到数组中
而日期为$1.0}
//返回5个结果
用于locationRatingTupleArray.前缀(5)中的(位置、等级){
打印(位置、等级)
topFive.append(位置)
}
打印(“前五名是\(前五名)”)
completionHandler(前五名)
}
}
hmm它在firebase文档中抛出了一个错误?FIRDocumentSnapshot GetDocumentWithSourceah my bad在两个不同的位置拥有myGroup.leave()。谢谢它看起来正在工作
func findTopSpots(completionHandler:([String])->Void) {
var topFive = [String]()
var locationRatingDictionary = [String:Double]()
let myGroup = DispatchGroup()
let locationsArray = ["wyoming", "kansas", "arkansas", "florida", "california"]
// Use the days to find the most common month
let calendar = NSCalendar.current
var monthArray = [String]()
var date = self.departureDate!
let endDate = self.returnDate!
// Formatter for printing the month name
let fmt = DateFormatter()
fmt.dateFormat = "MMMM"
// Add each days month to an array
while date <= endDate {
date = calendar.date(byAdding: .day, value: 1, to: date)!
monthArray.append(fmt.string(from: date))
}
// Return the primary month from function
let primaryMonth = findMostCommonMonthInArray(array: monthArray).lowercased()
// Create a dictionary of location:rating for the primary month
for doc in locationsArray {
myGroup.enter() self.db.collection("locations").document(doc).collection("historic").document(primaryMonth).getDocument { (document, err) in
if let document = document, document.exists {
let rating = document["rating"] as? Double
locationRatingDictionary[doc] = rating
} else {
print("Document does not exist")
}
myGroup.leave()
}
}
myGroup.notify(queue:.main) {
//---- THE CODE BELOW WILL NOT PRINT WITH ANY VALUES ----//
print(locationRatingDictionary)
// Sort the tuple array by rating
let locationRatingTupleArray = locationRatingDictionary.sorted{ $0.value > $1.value }
// Return 5 results
for (location,rating) in locationRatingTupleArray.prefix(5) {
print(location,rating)
topFive.append(location)
}
print("top five are \(topFive)")
completionHandler(topFive)
}
}