2016-11-23 83 views
0

我有2个参考(以相同的路径),一个侦听待办订单和另一个侦听完成的订单。所有用于特定位置,用户可以改变。火力地堡+斯威夫特:removeAllObservers不工作?

我现在使用的机制是这样的:

  1. 创建一个阵列,将存储火力地堡引用
  2. 之前我observe事件挂单,推那个火力地堡参考到我的数组
  3. 之前我observe事件已完成的订单,推动这一火力地堡参考到我的数组
  4. 当用户切换自己的位置,删除所有观察员在我的阵列中的所有引用。清空,并启动监听在新位置挂起/已完成订单(步骤2和3)

我的代码如下所示:

struct Firebase { 

    private let ORDERS_PATH = "locations-orders" 

    private static var references = [FIRDatabaseReference]() 

    static func observePendingOrders(lId: String, f: @escaping (AppState.Order) ->()) { 
    print("observing orders for \(ORDERS_PATH)/\(lId)") 

    let pendingOrdersReference = FIRDatabase.database().reference(withPath: "\(ORDERS_PATH)/\(lId)") 
    self.references.append(pendingOrdersReference) 

    pendingOrdersReference 
     .child(dateKeyToday()) 
     .queryOrdered(byChild: "created_at") 
     .observe(.childAdded, with: { firebaseSnapshot in 
     ... 

     print("order received for \(ORDERS_PATH)/\(lId)") 
     } 
    ) 
    } 

    static func fetchCompletedOrders(lId: String, f: @escaping ([AppState.Order]) ->()) { 
    print("observing completed orders for \(lId)") 

    let completedOrdersReference = FIRDatabase.database().reference(withPath: "\(ORDERS_PATH)/\(lId)") 
    self.references.append(completedOrdersReference) 

    completedOrdersReference 
     .child(dateKeyToday()) 
     .queryOrdered(byChild: "status_updated_at") 
     .observe(.value, with: { firebaseSnapshot in 
     ... 
     } 
    ) 
    } 

    static func removeAllOrderObservers() { 
    for reference in references { 
     print("removing reference \(reference)") 
     reference.removeAllObservers() 
    } 
    self.references = [] 
    } 

} 

然而,当我登录订单的位置我正在看的,它看起来像即使我切换位置的老观察员还在听订单。这是我的日志:

observing orders for locations-orders/9RC4H9ZAE457E // first location 
observing completed orders for 9RC4H9ZAE457E 
removing reference https://mydb-123.firebaseio.com/locations-orders/9RC4H9ZAE457E // switch locations, remove all existing observers for location 9RC4H9ZAE457E 
removing reference https://mydb-123.firebaseio.com/locations-orders/9RC4H9ZAE457E 
observing orders for locations-orders/1JS53G0TT5ZQD // start listening for orders in new location. notice the new id: 1JS53G0TT5ZQD 
observing completed orders for 1JS53G0TT5ZQD 
order received for locations-orders/9RC4H9ZAE457E // <-- why is this still showing up? 
order received for locations-orders/1JS53G0TT5ZQD 
order received for locations-orders/1JS53G0TT5ZQD 
order received for locations-orders/9RC4H9ZAE457E // <-- and this one too?? 
order received for locations-orders/1JS53G0TT5ZQD 
order received for locations-orders/1JS53G0TT5ZQD 

===更新=== 我甚至尝试把手,它不工作:

struct Firebase { 

    private static var handles = [UInt]() 
    private static var references = [FIRDatabaseReference]() 

    static func observePendingOrders(lId: String, f: @escaping (AppState.Order) ->()) { 
    print("observing orders for \(ORDERS_PATH)/\(lId)") 

    let pendingOrdersReference = FIRDatabase.database().reference(withPath: "\(ORDERS_PATH)/\(lId)") 
    self.references.append(pendingOrdersReference) 

    let handle = pendingOrdersReference 
     .child(dateKeyToday()) 
     .queryOrdered(byChild: "created_at") 
     .observe(.childAdded, with: { firebaseSnapshot in 
     ... 
     } 
    ) 

    handles.append(handle) 
    } 

    static func fetchCompletedOrders(lId: String, f: @escaping ([AppState.Order]) ->()) { 
    print("observing completed orders for \(ORDERS_PATH)/\(lId)") 

    let completedOrdersReference = FIRDatabase.database().reference(withPath: "\(ORDERS_PATH)/\(lId)") 
    self.references.append(completedOrdersReference) 

    let handle = completedOrdersReference 
     .child(dateKeyToday()) 
     .queryOrdered(byChild: "status_updated_at") 
     .observe(.value, with: { firebaseSnapshot in 
     ... 
     } 
    ) 
    handles.append(handle) 
    } 

    static func removeAllOrderObservers() { 
// for reference in references { 
//  print("removing reference \(reference)") 
//  reference.removeAllObservers() 
// } 
//  
    if !references.isEmpty { 
     let ref = references[0] 
     for handle in handles { 
     print("removing handle \(handle)") 
     ref.removeObserver(withHandle: handle) 
     } 
     self.references = [] 
    } 
    } 
} 
+0

我的第一个问题是,你为什么做这个?一旦你添加了一个观察者,它会一直观察,并在关联事件时调用闭包。不需要在数组中保持对其的引用。在这种情况下,订单节点中发生的任何事件都将通知您的应用程序。 – Jay

+0

嘿Jay。应用程序是这样使用的:用户选择一个位置并查看该位置的所有订单。当订单切换位置时,​​它现在应该只显示新位置的订单,而不是旧订单 – Edmund

+0

它也看起来像您正在观察相同位置的.childAdded和.value? – Jay

回答

0

我想我可能已经解决了吗?所以这是因为我确实观察到引用,以便删除所有观察员的父节点没有做任何事情,因为你必须在你观察特定的节点,除去它的子节点上。

let pendingOrdersReference = FIRDatabase 
    .database() 
    .reference(withPath: "\(ORDERS_PATH)/\(lId)") 
    .child(dateKeyToday()) // <---- added this thing 

这是我的最终解决方案,这似乎是工作:

struct Firebase { 
    private static var references = [FIRDatabaseReference]() 

    static func observePendingOrders(lId: String, f: @escaping (AppState.Order) ->()) { 
    print("observing orders for \(ORDERS_PATH)/\(lId)") 

    let pendingOrdersReference = FIRDatabase 
     .database() 
     .reference(withPath: "\(ORDERS_PATH)/\(lId)") 
     .child(dateKeyToday()) 
    self.references.append(pendingOrdersReference) 

    ... 
    } 

    static func fetchCompletedOrders(lId: String, f: @escaping ([AppState.Order]) ->()) { 
    print("observing completed orders for \(ORDERS_PATH)/\(lId)") 

    let completedOrdersReference = FIRDatabase 
     .database() 
     .reference(withPath: "\(ORDERS_PATH)/\(lId)") 
     .child(dateKeyToday()) 
    self.references.append(completedOrdersReference) 

    ... 

    } 

    static func removeAllOrderObservers() { 
    for reference in references { 
     print("removing reference \(reference)") 

     reference.removeAllObservers() 
    } 
    self.references = [] 
    } 

}