gpt4 book ai didi

swift - 如何在 Swift 中使用异步循环创建函数?

转载 作者:搜寻专家 更新时间:2023-11-01 07:05:29 24 4
gpt4 key购买 nike

我正在为图书馆创建一个应用程序。我正在尝试获取用户已从 Firebase checkout 的所有书籍,但我尝试使该函数与 DispatchGroup 异步的尝试似乎没有奏效。我怀疑这是因为在函数内部发现了 for-in 循环。

    func fetchHistory() {

if items.count > 0 {
items.removeAll()
}

let myGroup = DispatchGroup()
myGroup.enter()

var itemNames = [String]() // this holds the names of the child values of /users/uid/items/ <-- located in Firebase Database
guard let uid = fAuth.currentUser?.uid else {return}
fData.child("users").child(uid).child("items").observe(.value, with: { snapshot in

// make sure there is at least ONE item in the history
if snapshot.childrenCount > 0 {
let values = snapshot.value as! NSDictionary
for i in values.allKeys {
itemNames.append(i as! String)
}

print(itemNames)
let uid = fAuth.currentUser!.uid // get the UID of the user
for item in itemNames {
fData.child("users").child(uid).child("items").child(item).observe(.value, with: { snapshot in
let values = snapshot.value as! NSDictionary
let bookTitle = values["title"] as! String
print(bookTitle)
let bookAuthor = values["author"] as! String
print(bookAuthor)
let bookCoverUrl = values["coverUrl"] as! String
print(bookCoverUrl)
let bookStatus = values["status"] as! String
print(bookStatus)
let bookDueDate = values["dueDate"] as! String
print(bookDueDate)

let book = Book(name: bookTitle, author: bookAuthor, coverUrl: bookCoverUrl, status: bookStatus, dueDate: bookDueDate)
self.items.append(book)
})
}
self.booksTable.isHidden = false
} else {
self.booksTable.isHidden = true
}

})

myGroup.leave()
myGroup.notify(queue: DispatchQueue.main, execute: {
self.booksTable.reloadData()
print("Reloading table")
})

}

这是 print() 语句的输出:

########0
Reloading table
["78DFB90A-DE5B-47DE-ADCA-2DAB9D43B9C8"]
Mockingjay (The Hunger Games, #3)
Suzanne Collins
https://images.gr-assets.com/books/1358275419s/7260188.jpg
Checked
Replace

前两行输出应该在其他所有内容打印之后打印。我真的需要一些帮助,我已经坚持了几个小时。谢谢!

编辑:根据要求,这是我的 Firebase 结构:

users:
meZGWn5vhzXpk5Gsh92NhSasUPx2:
ID: "12345"
firstname: "Faraaz"
items:
78DFB90A-DE5B-47DE-ADCA-2DAB9D43B9C8
author: "Suzanne Collins"
coverUrl: "https://images.gr assets.com/books/1358275419s/..."
dueDate: "Date"
status: "Checked"
title: "Mockingjay (The Hunger Games, #3)"
type: "regular"

最佳答案

几个问题:

  1. 模式是leave 必须在异步调用的完成处理程序内部 中调用。您希望这是闭包内执行的最后一件事,因此您可以将其添加为完成处理程序闭包内的最后一行。

    或者我更喜欢使用 defer 子句,这样您不仅知道它将是闭包中执行的最后一件事,而且:

    • 你确保你离开,即使你后来在你的闭包中添加了任何“提前退出”;和
    • enterleave 调用在代码中视觉上彼此紧挨着显示,这样您就不必在闭包的底部进行视觉搜索以确保它被正确调用。
  2. 如果您想在 for 循环中等待异步调用,您也必须将其添加到那里。

  3. 一个非常小的问题,但您可能希望在成功解包 uid 之前不创建组。如果您可以返回而不执行任何异步代码,为什么要创建 DispatchGroup

因此,也许:

func fetchHistory() {

if items.count > 0 {
items.removeAll()
}

var itemNames = [String]()
guard let uid = fAuth.currentUser?.uid else {return}

let group = DispatchGroup()

group.enter()

fData.child("users").child(uid).child("items").observe(.value, with: { snapshot in

defer { group.leave() } // in case you add any early exits, this will safely capture

if snapshot.childrenCount > 0 {
...
for item in itemNames {

group.enter() // also enter before we do this secondary async call

fData.child("users").child(uid).child("items").child(item).observe(.value, with: { snapshot in

defer { group.leave() } // and, again, defer the `leave`

...
})
}
...
} else {
...
}
})

group.notify(queue: .main) {
self.booksTable.reloadData()
print("Reloading table")
}
}

关于swift - 如何在 Swift 中使用异步循环创建函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48309528/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com