2015-07-17 7 views
12

Dokumentation besagt, dass Sie observeEventType:withBlock aufrufen müssen, um einen Beobachter zu entfernen, wenn Sie ihn nicht mehr benötigen.Firebase: Wenn removeObserverWithHandle in swift aufgerufen werden soll

Ich habe Proben gesehen, wo es innerhalb ViewDidDisAppear aufgerufen wird. Ich finde auch einen Obj-C-Code, der diese Methode innerhalb von deinit genannt wird, was in Swift nicht notwendig ist.

In meiner einfachen App möchte ich jedoch Daten synchronisiert werden, solange ich in der App bin. Wenn dies der Fall ist, muss ich observeEventType:withBlock jemals anrufen?

Ich habe den Chat-Swift-Beispielcode auf der Firebase-Website überprüft und observeEventType:withBlock nicht gefunden.

Bedeutet es, es ist in Ordnung, nicht zu rufen observeEventType:withBlock:. Wenn ich möchte, dass der Beobachter eingeschaltet ist, wenn die App verwendet wird?

Vielen Dank.

UPDATE

Dank Jay und David. Ich sehe es sinnvoll in ViewWillAppear zu beobachten und in ViewDidDisappear zu entfernen.

Ich verwende jedoch observeEventType, um jede Wertänderung für den Knoten zu überwachen, und würde die Benutzeroberfläche aktualisieren, wenn eine vorhanden ist. Wenn ich es in ViewWillAppear setzen:

override func viewWillAppear(animated: Bool) { 
    super.viewWillAppear(animated) 

    ref.observeEventType(.Value, withBlock: { snap in { 
     // **update UI if there is any Value change** 
    }) 
    } 

Das Problem mit ihm in viewWillAppear setzen ist, dass es jedes Mal aufgerufen wird, die Ansicht, unabhängig von Wertänderung erscheint oder nicht. Aus diesem Grund wird der Snapshot heruntergeladen und meine Benutzeroberfläche wird jedes Mal aktualisiert, wenn ich zur Ansicht zurückkehre. Dies wird kontraproduktiv.

Ich habe auch versucht ChildAdded/ChildRemoved, es jedoch nur den letzten Knoten zurückkehrt, nicht der Weg von meinem ref:

Zum Beispiel, wenn ich hinzufügen/child1/child2/child3/Wert auf ref ChildAdded würde nur child3/value zurückgeben.

Also, wenn ich Wert zu beachten habe, scheint es, als ob es in ViewDidLoad ist besser? Auf diese Weise erhält es den Snapshot einmal, wenn die Ansicht geladen wird, und würde sich bei jeder Änderung wiederholen, würde aber den Snapshot nicht erhalten, nur weil die Ansicht angezeigt wird.

+0

@David antwortet dies, da es aufhört zu beobachten, wenn die Ansicht nicht angezeigt wird. Es aktualisiert die Ansicht, wenn es angezeigt wird, aber das mag sein, was Sie sowieso wollen. Es gibt zwei andere mögliche Lösungen: 1) ref.observeEventType gibt tatsächlich ein Handle zurück. Speichern Sie dieses Handle als Eigenschaft. Wenn es null ist, handle = ref.observeEventType. Wenn es nicht Null ist, dann tu es nicht. 2) Bewege den observeEventType auf eine höhere Ebene. Angenommen, Sie initialisieren Ansichten aus dem App-Delegaten, nachdem sie eingerichtet wurden, und beobachten Sie dann Ereignistyp. – Jay

+0

Das ChildAdded-Ereignis sollte untersucht werden. Wenn Sie es versucht haben und es nur den letzten Knoten zurückgibt, dann gibt es einen Codierungsfehler. Es wird einmal ausgelöst, wenn Sie es nacheinander für jeden untergeordneten Knoten und dann nur für childAdded-Ereignisse aufrufen. Sie können diese Funktion verwenden, um die Benutzeroberfläche zunächst aufzufüllen (sie wird einmal für jedes Kind aufgerufen) und anschließend die Benutzeroberfläche aktualisieren (wird nur aufgerufen, wenn ein untergeordnetes Element hinzugefügt wird und nur das neue untergeordnete Element angezeigt wird). Wir verwenden selten Value-Ereignisse, da wir nach dem Laden von Daten nur über Änderungen informiert werden möchten. Das Implementieren von ChildAdded, ChildChanged und ChildRemoved behandelt das. – Jay

+0

Danke Jay. Nach ein paar Versuchen entschied ich mich, meinen Beobachter in viewDidLoad zu belassen, wechselte aber von der Beobachtung von Value zur Beobachtung von ChildAdded/Removed abhängig von meiner Verwendung. Danke für deinen Beitrag. – User5103156

Antwort

4

observeEventType: withBlock wird verwendet, um einen Knoten zu beobachten.

Sobald die App einen Knoten beobachtet, wird sie weiter beobachtet, es sei denn, Sie beenden entweder die App oder weisen Firebase an, die Beobachtung einzustellen.

Beobachtung So stoppen Sie entweder den Griff verwenden können, die zurückgegeben wurde, wenn Sie beobachten, wie diese begonnen:

//start observing and get a handle 
FirebaseHandle handle = [ref observeEventType:FEventTypeValue withBlock:^(FDatasnapshot* snapshot) { 
     // do some stuff with the snapshot data 
    }]; 

    [ref removeObserverWithHandle:handle]; //stop observing using the handle 

oder ähnliche

[ref removeAllObservers]; 
+0

Auch als Antwort auf die spezifische Frage des OP, müssen Sie es nicht in 'deinit' tun, Sie müssen es in' viewWillDisappear' (oder 'viewDidDisappear') tun. – Fattie

22

auf @ ausgezeichnete Antwort Jay zu bauen:

Erstellen Sie in einer UIViewController eine Referenz als Eigenschaft. Initialisieren Sie eine Referenz in viewDidLoad. Beobachten Sie Ereignisse in viewWillAppear.Entfernen Sie Beobachter in viewDidDisappear.

class MyViewController: UIViewController { 

    var ref: Firebase! 

    // Called only on load, great place to initialize 
    override func viewDidLoad() { 
    super.viewDidLoad() 
    ref = Firebase(url: "https://<YOUR-FIREBASE-APP>.firebaseio.com/updates") 
    } 

    // Can be called many times to go on screen 
    // Syncing should only occur when on view to conserve memory 
    override func viewWillAppear(animated: Bool) { 
    super.viewWillAppear(animated) 

    ref.observeEventType(.Value, withBlock: { snap in { 
     // do something with the data 
    }) 
    } 

    // Can be called many times to off screen 
    // Remove observers on the ref to conserve memory 
    override func viewDidDisappear(animated: Bool) { 
    super.viewDidDisappear(animated) 
    ref.removeAllObservers() 
    } 

} 

Per Ihre edit:

The problem with putting it in viewWillAppear is that, it gets called every time the view appears, regardless of Value change or not. Because of this, the snapshot is downloaded and my UI gets refreshed every time I return to the view. This becomes counterproductive. 

Firebase ist auf Geschwindigkeit ausgelegt. Dies sind die Dinge, die Sie dem Client überlassen, weil es mehrere Funktionen für diese Situationen hat.

Der Firebase-Client verfügt über ein integriertes Caching. Sofern Sie nicht ein Megabyte Daten in viewDidAppear herunterladen, ist das Update nominal. Wenn der Beobachter auf viewDidAppear feuert, heißt das nicht unbedingt, dass er die Daten erneut herunterlädt. Die viewDidAppear Funktion ist, wo Ihre Beobachter gehören.

FYI, ich bin ein Firebase-Mitarbeiter, der auf iOS arbeitet.

+0

Danke für deinen Kommentar, siehe mein Update oben. – User5103156

+0

Ich habe meine Antwort aktualisiert. –

+0

Vielen Dank! Es ist toll, wenn Sie Fragen haben. – User5103156

Verwandte Themen