2014-11-25 16 views
8

Ho un problema durante la rimozione di un osservatore Firebase nel mio codice. Ecco la ripartizione della struttura:Firebase rimozione osservatori

var ref = Firebase(url:"https://MY-APP.firebaseio.com/") 
var handle = UInt? 

override func viewDidLoad() { 
    handle = ref.observeEventType(.ChildChanged, withBlock: { 
     snapshot in 

     //Do something with the data 
    } 
} 

override func viewWillDisappear(animated: Bool) { 
    if handle != nil { 
     println("Removed the handle") 
     ref.removeObserverWithHandle(handle!) 
    } 
} 

Ora, quando lascio la viewcontroller, vedo che "Rimosso il manico" è stampato, ma quando torno al viewcontroller, il mio osservatore è chiamato due volte per ogni evento. Quando esco e torno di nuovo, si chiama tre volte. Ecc. Perché l'osservatore non viene rimosso?

Io chiamo anche ref.setValue("some value") più avanti nel codice, questo potrebbe avere qualcosa a che fare con esso?

+0

Anche questo problema ha appena inviato un bug report al supporto di Firebase. Dal momento che non è stato risolto in 2 mesi, potrebbe non essere risolto in qualsiasi momento presto – Cymric

+0

@Cymric Hey man, qualsiasi aggiornamento su questo? Qualsiasi risposta ? Ho davvero bisogno di alcune soluzioni qui. – Bonnke

+0

Purtroppo no. Ho presentato un programma di esempio che riproduceva il bug del team di supporto di Firebase 4 mesi fa e da allora non ha più avuto notizie. Ti suggerirei di provare la soluzione alternativa di Daniel K qui sotto. – Cymric

risposta

1

dato di aprile 2015 e il bug è ancora in giro mi piacerebbe proporre una soluzione per il problema:

  • mantenere un punto di riferimento delle maniglie (diciamo in un dizionario e prima di iniziare un nuovo osservatore per la lo stesso tipo di evento controlla se l'osservatore è già presente

Avere le maniglie in giro ha un ingombro molto basso (basato su alcuni commenti ufficiali :)), quindi non farà molto male.

+0

Scusate per la risposta lenta, ho iniziato a lavorare su altri progetti nel frattempo, quindi mi ci è voluto un po 'per provare i vostri consigli. Anche se non è l'ideale, fornisce una soluzione alternativa, quindi grazie per questo :) –

+0

Se stai utilizzando un riferimento di sé non incluso nel blocco, questo è un grosso problema. Devo modificare tutto il riferimento a debole o controllare se le istanze sono nul ogni volta? –

2

Pensavo che stavo avendo questo bug ma in realtà stavo cercando di rimuovere gli osservatori sul riferimento sbagliato.

CODICE ORIGINALE:

let ref: FIRDatabaseReference = FIRDatabase.database().reference() 
var childAddedHandles: [String:FIRDatabaseHandle] = [:] 

func observeFeedbackForUser(userId: String) { 
    if childAddedHandles[userId] == nil { // Check if observer already exists 

     // NOTE: - Error is caused because I add .child(userId) to my reference and 
     //  do not when I call to remove the observer. 

     childAddedHandles[userId] = ref.child(userId).observeEventType(.ChildAdded) { 
      [weak self] (snapshot: FIRDataSnapshot) in 

      if let post = snapshot.value as? [String:AnyObject], 
       let likes = post["likes"] as? Int where likes > 0 {    

       self?.receivedFeedback(snapshot.key, forUserId: userId)   
      } 
     } 
    } 
} 

func stopObservingUser(userId: String) { 
    // THIS DOES NOT WORK 

    guard let cah = childAddedHandles.removeValueForKey(userId) else { 
     print("Not observing user") 
     return 
    } 

    // Error! I did not add .child(userId) to my reference 
    ref.removeObserverWithHandle(cah) 
} 

FISSO CODICE:

func stopObservingUser(userId: String) { 
    // THIS WORKS 

    guard let cah = childAddedHandles.removeValueForKey(userId) else { 
     print("Not observing user") 
     return 
    } 

    // Add .child(userId) here 
    ref.child(userId).removeObserverWithHandle(cah) 
} 
0

osservatori deve essere rimosso lo stesso percorso di riferimento sono stati messi su. E per lo stesso numero di volte in cui sono stati emessi, o utilizzare ref.removeAllObservers() per ogni percorso.

Ecco un trucco che uso, di tenerlo in ordine:

var fbObserverRefs = [FIRDatabaseReference]() // keep track of where observers defined. 

... poi, messo osservatori in viewDidLoad():

fbObserverRefs.append(ref.child("user/\(uid)")) 
fbObserverRefs.last!.observe(.value, with: { snap in 
    // do the work... 
}) 

... poi, in viewWillDisappear() , prenditi cura di rimuovere eventuali osservatori emessi:

// Only true when popped from the Nav Controller stack, ignoring pushes of 
// controllers on top. 
if isBeingDismissed || isMovingFromParentViewController { 
    fbObserverRefs.forEach({ $0.removeAllObservers() }) 
} 
Problemi correlati