转义闭包捕获变异的“自我”参数,Firebase
Posted
技术标签:
【中文标题】转义闭包捕获变异的“自我”参数,Firebase【英文标题】:Escaping closure captures mutating 'self' parameter, Firebase 【发布时间】:2020-07-19 11:40:27 【问题描述】:我有以下代码,如何在不将结构更改为类的情况下完成此操作。转义闭包捕获变异的“自我”参数,
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)
【问题讨论】:
【参考方案1】:SwiftUI 视图可以在渲染周期中多次创建(重新创建)/复制,因此View.init
不适合加载一些外部数据。改为使用专用的视图模型类并仅在需要时显式加载。
喜欢
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()
【讨论】:
【参考方案2】:使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)")
//...
【讨论】:
以上是关于转义闭包捕获变异的“自我”参数,Firebase的主要内容,如果未能解决你的问题,请参考以下文章