[英]Escaping closure captures mutating 'self' parameter, Firebase
我有以下代碼,如何在不將結構更改為 class 的情況下完成此操作。 Escaping 閉包捕獲變異的“自我”參數,
struct RegisterView:View {
var names = [String]()
private func LoadPerson(){
FirebaseManager.fetchNames(success:{(person) in
guard let name = person.name else {return}
self.names = name //here is the error
}){(error) in
print("Error: \(error)")
}
init(){
LoadPerson()
}a
var body:some View{
//ui code
}
}
Firebasemanager.swift
struct FirebaseManager {
func fetchPerson(
success: @escaping (Person) -> (),
failure: @escaping (String) -> ()
) {
Database.database().reference().child("Person")
.observe(.value, with: { (snapshot) in
if let dictionary = snapshot.value as? [String: Any] {
success(Person(dictionary: dictionary))
}
}) { (error) in
failure(error.localizedDescription)
}
}
}
SwiftUI 視圖可以在渲染周期中多次創建(重新創建)/復制,因此View.init
不適合加載一些外部數據。 改用專用視圖 model class 並僅在需要時顯式加載。
喜歡
class RegisterViewModel: ObservableObject {
@Published var names = [String]()
func loadPerson() {
// probably it also worth checking if person has already loaded
// guard names.isEmpty else { return }
FirebaseManager.fetchNames(success:{(person) in
guard let name = person.name else {return}
DispatchQueue.main.async {
self.names = [name]
}
}){(error) in
print("Error: \(error)")
}
}
struct RegisterView: View {
// in SwiftUI 1.0 it is better to inject view model from outside
// to avoid possible recreation of vm just on parent view refresh
@ObservedObject var vm: RegisterViewModel
// @StateObject var vm = RegisterViewModel() // << only SwiftUI 2.0
var body:some View{
Some_Sub_View()
.onAppear {
self.vm.loadPerson()
}
}
}
使names
屬性@State
變量。
struct RegisterView: View {
@State var names = [String]()
private func LoadPerson(){
FirebaseManager.fetchNames(success: { person in
guard let name = person.name else { return }
DispatchQueue.main.async {
self.names = [name]
}
}){(error) in
print("Error: \(error)")
}
}
//...
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.