我在帮助器类中使用此函数来获取用户的行程。它一直在倾听新的变化:
import Foundation
import Firebase
class APICardService: NSObject {
class func fetchTrips(forID userID: String, completion: @escaping ([Trip]) -> Void) {
let path = "users/\(userID)/trips"
Database.database().reference().child(path).queryOrdered(byChild: "timestamp").observe(.value) { (snapshot) in
var trips = [Trip]()
for child in snapshot.children {
if let child = child as? DataSnapshot {
if let dict = child.value as? [String: Any] {
let trip = Trip(key: child.key, dbValues: dict)
trips.append(trip)
}
}
}
completion(trips)
}
}
}
class MyViewController: UIViewController {
// but what if the userID changes? I have no way to stop the current observer and start a new one
internal func fetchCards() {
guard let userID = APIAuthService.getUserID() else { return }
APICardService.fetchTrips(forID: userID) { trips in
self.trips = trips.reversed() // show most recent first
self.addAnnotations(for: trips)
self.collectionView.reloadData()
}
}
}
问题在于,每当用户注销并登录到新帐户时,此观察者仍将监听数据中的新值更改,但由于userID已更改,因此无法正常工作。我该如何处理?我可以以某种方式删除观察者,但这很复杂,因为我们在一个单独的类中,我不知道如何处理它。
答案 0 :(得分:1)
正如@PrashantTukadiya所说。 尝试做这样的事情:
struct User {
var id: String
...
}
class UserHolder {
static var shared: UserHolder = UserHolder() // Singleton
var currentUser: User? {
willSet {
// Remove all the registered firebase handlers associated with the user
firebaseHandles.forEach({ $0.0.removeObserver(withHandle: $0.1) })
}
}
var firebaseHandles: [(DatabaseReference, UInt)] = []
// Note: Try to add all the firebase handles you register to "firebaseHandles"
// array. The more adequate solution is to make this class register
// the listeners, not all other classes.
}
答案 1 :(得分:1)
在班级APICardService
中创建这些全局变量
static var refHandle:DatabaseHandle? = nil
static var ref:DatabaseReference? = nil
在您的方法func fetchTrips(forID userID: String, completion: @escapin
分配像这样的全局变量
let path = "users/\(userID)/trips"
ref = Database.database().reference().child(path)
refHandle = ref?.queryOrdered(byChild: "timestamp").observe(.value) { (snapshot) in
现在你有了观察者的参考资料
只需在您的课程中添加以下方法
class func removeObserverForFetchTrip() {
if let refHandleValue = refHandle {
ref?.removeObserver(withHandle: refHandleValue)
}
}
当用户注销时,只需调用此方法
希望它有用