Swift3、Firebase completionHandler被执行了两次
Swift 3, Firebase completion Handler is executed twice
我的用例 -
我有从 Firebase 获取的项目列表。下面是我从 HomeViewController 调用的 loadItems() 函数 -
viewDidLoad() 并使用获取的数据更新 tableView。
func loadItems() {
Database.database().reference().child("items").observe(.value, with: { snapshot in
var fetchedItems = [Item]()
guard let receivedvalue = snapshot.value as? [String: Any] else {
print("Received null")
return
}
print(receivedvalue)
for (key, value) in receivedvalue {
let item = Item(id: Int(key)!, json: value as! [String : Any])
fetchedItems.append(item!)
}
self.items = fetchedItems
self.tableView.reloadData()
})
}
我正在保存一个项目并从 CreateViewController 返回到 HomeViewController,我是 - 在 Firebase 中保存项目,将项目附加到预取数组,重新加载 tableView。
func addItem(item: Item?) {
rootRef = Database.database().reference()
let id = String(describing: item.id!)
let itemRef = self.rootRef.child("items").child(id)
itemRef.setValue(["name": item.name!, "type": item.type!])
items.append(item!)
self.tableView.reloadData()
}
重新加载 tableView 后,它会进入 loadItems() 中存在的 Firebase GET 调用处理程序。
当我在 viewDidLoad() 期间获取所有项目时,处理程序将执行一次。即使我没有在创建工作流中调用 loadItems(),但第二次执行 Firebase GET 调用处理程序是否有任何原因?
当使用 .observe(.value 时,它会向该节点添加一个观察者,并且 any 更改该节点(添加, change, remove) 将触发闭包中的代码。
如果您想离开观察者以便收到更改通知,正确的流程是简单地将数据写入 Firebase,然后让闭包加载数据并填充 tableView。
但是,这样做的缺点是 .value 会加载节点中的所有数据。您可能想看看为 .childAdded、.childChanged 和 .childRemoved 添加单独的观察者。那些只会加载被修改的节点。
如果您只想加载一次数据(例如在启动时填充数据源),请使用会触发一次且不会留下观察者的 observeSingleEvent。
然后将数据存入Firebase,手动添加到数组中,重新加载tableView。
请参阅文档 Read Data Once 部分。
我的用例 - 我有从 Firebase 获取的项目列表。下面是我从 HomeViewController 调用的 loadItems() 函数 - viewDidLoad() 并使用获取的数据更新 tableView。
func loadItems() {
Database.database().reference().child("items").observe(.value, with: { snapshot in
var fetchedItems = [Item]()
guard let receivedvalue = snapshot.value as? [String: Any] else {
print("Received null")
return
}
print(receivedvalue)
for (key, value) in receivedvalue {
let item = Item(id: Int(key)!, json: value as! [String : Any])
fetchedItems.append(item!)
}
self.items = fetchedItems
self.tableView.reloadData()
})
}
我正在保存一个项目并从 CreateViewController 返回到 HomeViewController,我是 - 在 Firebase 中保存项目,将项目附加到预取数组,重新加载 tableView。
func addItem(item: Item?) {
rootRef = Database.database().reference()
let id = String(describing: item.id!)
let itemRef = self.rootRef.child("items").child(id)
itemRef.setValue(["name": item.name!, "type": item.type!])
items.append(item!)
self.tableView.reloadData()
}
重新加载 tableView 后,它会进入 loadItems() 中存在的 Firebase GET 调用处理程序。
当我在 viewDidLoad() 期间获取所有项目时,处理程序将执行一次。即使我没有在创建工作流中调用 loadItems(),但第二次执行 Firebase GET 调用处理程序是否有任何原因?
当使用 .observe(.value 时,它会向该节点添加一个观察者,并且 any 更改该节点(添加, change, remove) 将触发闭包中的代码。
如果您想离开观察者以便收到更改通知,正确的流程是简单地将数据写入 Firebase,然后让闭包加载数据并填充 tableView。
但是,这样做的缺点是 .value 会加载节点中的所有数据。您可能想看看为 .childAdded、.childChanged 和 .childRemoved 添加单独的观察者。那些只会加载被修改的节点。
如果您只想加载一次数据(例如在启动时填充数据源),请使用会触发一次且不会留下观察者的 observeSingleEvent。
然后将数据存入Firebase,手动添加到数组中,重新加载tableView。
请参阅文档 Read Data Once 部分。