2016-09-07 4 views
0

Ich definierte eine Klasse in einem Projekt, um meine Datenbank in Firebase eingerichtet verwalten. Das Folgende habe ich bisher mit der Klasse gemacht.In Firebase, abgerufene Daten nicht aus der. ObserveEventType-Methode

import Foundation 
import Firebase 

class db{ 
    class func getPrim() -> [String]{ 
     var ret = [String]() 

     let ref = FIRDatabase.database().reference() 

     ref.child("bunya1").observeEventType(FIRDataEventType.Value, withBlock: { 
      s in 

      ret = s.value! as! [String] 

     }) 

     print("ret: \(ret)") 
     return ret 
    } 
} 

und das Verfahren wird in einem print() Verfahren, wie print(db.getPrim()) genannt. Aber was die Konsole (oder Terminal? Sowieso der Bildschirm am unteren Rand von xcode ..) sagt, ist nur ein leeres Array. Ich habe die obige Aussage mit print("-----------------------") begrüßt.

----------------------- 
ret: [] 
[] 
----------------------- 
2016-09-07 20:23:08.808 이모저모[36962:] <FIRAnalytics/INFO> Successfully created Firebase Analytics App Delegate Proxy automatically. To disable the proxy, set the flag FirebaseAppDelegateProxyEnabled to NO in the Info.plist 
2016-09-07 20:23:08.815 이모저모[36962:] <FIRAnalytics/INFO> Firebase Analytics enabled 

scheint, wie in ret.observeEventType() Verfahren findet nicht seinen Wert aus dem Verfahrensblock. Soweit ich weiß, sollen die Daten aufbewahrt werden. Kann mir jemand einen Tipp geben? Ich verstehe immer noch nicht, wie der Code-Block als Methodenparameter funktioniert. Thnx !!

+0

Ich schrieb 'print (" ret: \ (ret) ")' direkt unter der zuweisenden Anweisung 'ret = s.value! wie! [Zeichenfolge] '. Dieser wurde ein paar Sekunden nachdem die Konsolennachrichten, die ich gepostet hatte, aufgetaucht waren, gedruckt. –

+2

Alle Firebase-Operationen sind per Definition asynchron. Wenn also die Druckanweisungen aufgerufen werden, wurden die Daten aus dem Firebase noch nicht abgerufen. –

+0

@ AndréKool poste es als Antwort –

Antwort

3

Alle Firebase-Operationen sind per Definition asynchron, was bedeutet, dass Ihr Programm nicht auf die Daten von Firebase wartet, bevor Sie zur nächsten Anweisung in Ihrem Code gehen. Wenn also die Druckanweisungen aufgerufen werden, wurden die Daten aus dem Firebase noch nicht abgerufen.

Weitere Informationen finden Sie unter this answer.

0

André (und der Link zu Vikrum's Antwort) sind in der Tat, warum das passiert. Aber es ist in der Regel am einfachsten zu verstehen, wenn Sie ein paar Log-Anweisungen, um Ihren Code hinzufügen:

class func getPrim() -> [String]{ 
    let ref = FIRDatabase.database().reference() 

    print("Before observer"); 
    ref.child("bunya1").observeEventType(FIRDataEventType.Value, withBlock: { 
     s in 

     print("In observer block"); 

    }) 
    print("After observer"); 

    return "..." 
} 

Wenn Sie diesen Code ausführen, wird die Protokollierung in dieser Reihenfolge:

Bevor Beobachter

nach dem Beobachter

In Beobachter Rückruf

Dies ist wahrscheinlich nicht die Reihenfolge, in der Sie sie erwartet haben. Aber es erklärt definitiv, warum Sie ein leeres Array in Ihrem Snippet zurückgeben. Wenn der Code innerhalb des Blocks noch nicht ausgeführt wurde, wurde das Element noch nicht zum Array hinzugefügt.

Der Grund, warum diese Reihenfolge umgekehrt ist, ist, wie André und Vikrum sagen: Der Aufruf von Firebase geschieht asynchron. Da es einige Zeit dauern kann (vor allem, wenn Sie zum ersten Mal auf die Datenbank zugreifen), wird der Swift-Code weiterhin ausgeführt, um sicherzustellen, dass die App reaktionsfähig bleibt. Sobald die Daten von Firebase zurückkommen, wird Ihr Block aufgerufen (aus diesem Grund wird er manchmal als "Rückruf" bezeichnet) und Sie erhalten die Daten.

+0

Danke! Dann sollte ich die 'sleep()' Methode oder etwas verwenden, um auf die '.observeEventType()' zu warten, um die Ausführung zu beenden? –

+0

Nein. Sie sollten weg von dem "zuerst tun, dann tue das" denken und stattdessen ein "wenn das passiert, werde ich das als Antwort tun" Einstellung. Seht Vikrum's Antwort, mit der André ein Beispiel dafür hat. –

Verwandte Themen