我正在嘗試獲取特定推文的所有回復。我正在使用 Firestore 來保存推文、回復等。下面是 Tweet 結構中的回復屬性。我總是檢查并且 compactMap 函式確實回傳了一個推文陣列。
var replies: [Tweet] {
get async {
let documents = try? await documentRef?.collection("replies").getDocuments().documents
if let documents {
// I checked and it does return replies as I can print them on the terminal
return documents.compactMap { doc in
return try? doc.data(as: Tweet.self)
}
}
return []
}
}
但是在 SwiftUI 中,當我分配并列印出 self.replies 屬性時,它會以一個空陣列的形式出現。
struct TweetDetailView: View {
let tweet: Tweet
@State private var replies: [Tweet] = []
init(tweet: Tweet) {
self.tweet = tweet
setup()
}
private func setup() {
Task {
self.replies = await self.tweet.replies
print(self.replies) // This prints an empty array WHY
}
}
有任何想法嗎?
uj5u.com熱心網友回復:
您的示例中的問題實際上與異步代碼沒有任何關系——它與@State設定方式有關。例如,這段代碼,沒有任何異步,遭受同樣的“問題”:
struct ContentView: View {
@State private var count = 0
init() {
launchTask()
}
func launchTask() {
let incremented = self.count 1
self.count = incremented
print(self.count)
}
var body: some View {
VStack {
Text("hello, world")
}
.frame(width: 500, height: 500)
}
}
但是,這里有幾件事出了問題:
- 最直接的是,您不能也不應該依賴在
@State設定值后立即更改它——它將在下一個渲染回圈中設定。例如,如果您incremented在我的示例中列印,它將是人們期望的值。在您的示例中,您可以執行以下操作:
var result = await self.tweet.replies
print(result)
self.replies = result
而且,它也將列印預期結果(假設您的除錯是正確的并且異步 getter 確實回傳了結果)。
- 第二個問題雖然與您的問題沒有直接關系,但您永遠不應該在 SwiftUI 中做任何“作業
init”View。相反,使用.task { ... }or.onAppear { ... }修飾符來啟動Task. 否則,您的函式將在 的每個init 上運行View,這可能會運行很多次。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/516974.html
標籤:IOS迅捷
