2016-06-28 24 views
0

Ich versuche, einige Daten von einer GET-Anfrage zu speichern. Ich benutze StartCoroutine zur Anfrage und ich benutze Lambda-Ausdruck zum Speichern der Daten.GET Anfrage nicht speichern Daten

My-Code ist dies:

Using UnityEngine; 
    using System.Collections; 

    public class Test : MonoBehaviour { 

// Use this for initialization 
public void Start() { 
    string url1 = "http://localhost/virtualTV/query/?risorsa="; 

    string ciao = "http://desktop-pqb3a65:8080/marmotta/resource/ef299b79-35f2-4942-a33b-7e4d7b7cbfb5"; 
    url1 = url1 + ciao; 

    WWW www1 = new WWW(url1); 

    var main=new JSONObject(JSONObject.Type.OBJECT); 
    var final= new JSONObject(JSONObject.Type.OBJECT);; 
    StartCoroutine(firstParsing((value)=>{main = value; 
     final= main.Copy(); 
     Debug.Log(main); 
    })); 
    Debug.Log(final); 
} 

public IEnumerator firstParsing(System.Action<JSONObject> callback) 
{ 
    string url2 = "http://localhost/virtualTV/FirstQuery/?risorsa="; 
    string ciao = "http://desktop-pqb3a65:8080/marmotta/resource/ef299b79-35f2-4942-a33b-7e4d7b7cbfb5"; 
    url2 = url2 + ciao; 
    WWW www2 = new WWW(url2); 
    yield return www2; 
    string json = www2.text; 

    //Parsing del json con creazione di un array 
    var firstjson = new JSONObject(json); 
    var tempVideo = new JSONObject(JSONObject.Type.OBJECT); 
    var array2 = new JSONObject(JSONObject.Type.OBJECT); 

      tempVideo.AddField ("id", firstjson.GetField ("id")); 
      tempVideo.AddField ("type", firstjson.GetField ("type")); 
      tempVideo.AddField ("url", firstjson.GetField ("url")); 
      array2.Add (tempVideo); 

    yield return array2;  
    callback (array2); 
    Debug.Log ("First Run" + array2); 

} 

Wenn ich versuche, nach dem Befehl FINAL zu verwenden,

final=main.copy() 

es leer ist. Kannst du mir helfen, den Wert in der Variablen final zu speichern? Danke allen.

+0

Was ist die Ausgabe von 'Debug.Log (main);'? –

+0

Es enthält die JSON, die ich im Finale speichern möchte, kann es nicht Variable in Variable Finale kopieren, wenn ich final in StartCoroutine print es enthält JSON, danach ist es leer – user3836982

+0

Erhalten Sie irgendwelche Fehler? –

Antwort

3

Die Ausführung einer Coroutine ist über viele Frames verteilt. Wenn eine Koroutine auf eine yield return-Anweisung trifft, kehrt sie zur aufrufenden Methode zurück, die die Ausführung beendet, bis die Aufgabe beendet ist.


In Ihrem Fall die Debug.Log(final) Anweisung in Start ausführt, sobald yield return www2; in firstParsing ausgeführt wird. Der Callback wurde noch nicht aufgerufen, weshalb final leer ist.

Um den Wert in final zuzugreifen, nachdem es außerhalb die Callback-Funktion zugewiesen wurde, erhalten Sie eine bool gesetzt haben, die auf true nach gesetzt final in der Callback zugeordnet ist. Etwas wie folgt aus:

StartCoroutine(firstParsing((value)=>{main = value; 
    final= main.Copy(); 
    Debug.Log(main); 
    isFinalAssigned = true; 
})); 

// In another method 
if(isFinalAssigned) 
{ 
    // Access final 
} 

Sie müssen beachten, dass die oben if Aussage ist nur sinnvoll in einem Verfahren, das in regelmäßigen Abständen wie Update genannt wird. Wenn Sie auf final in einer Methode zugreifen, die nur einmal aufgerufen wird (wie OnEnable), müssen Sie warten, bis final zugewiesen wird. Sie können für diese Aufgabe eine andere Koroutine verwenden wie

IEnumerator DoSomethingWithFinal() 
{ 
    while(!isFinalAssigned) 
     yield return null; // Wait for next frame 
    // Do something with final 
} 

Der einfachste Weg zu verbrauchen ist (Zugang) final in Ihrem callback.

EDIT2: Von Ihren Kommentaren können Sie etwas wie folgt tun. Sie werden verwenden, um Coroutinen zu verwenden, weil das Blockieren des Hauptspielthreads keine gute Idee ist.

private JSONObject final = null; // Make final a field 

Wo auch immer Sie final verwenden, haben Sie zwei Möglichkeiten.

  1. Verwenden Sie einen Null-Check if(final == null) return; Dies kann unpraktisch sein.
  2. Warten Sie, bis final in einer Coroutine zugewiesen wird und tun Sie etwas als Rückruf. Nur so können Sie das tun, was Sie wollen.

Suchen Sie unten nach der Implementierung.

// Calls callback after final has been assigned 
IEnumerator WaitForFinal(System.Action callback) 
{ 
    while(final == null) 
     yield return null; // Wait for next frame 
    callback(); 
} 

// This whole method depends on final. 
// This should be similar to your method set up if you have 
// good coding standards (not very long methods, each method does only 1 thing) 
void MethodThatUsesFinal() 
{ 
    if (final == null) 
    { 
     // Waits till final is assigned and calls this method again 
     StartCoroutine(WaitForFinal(MethodThatUsesFinal)); 
     return; 
    } 

    // use final 
} 
+0

Können Sie mir ein Beispiel für die einfachste Methode geben, um auf die finale Anzeigenvariable zuzugreifen? Becausa ich versuche, die erste Methode zu verwenden, aber es die Variable nie endgültig zuweisen. Vielen Dank – user3836982

+0

Ich benutze die Variable final in der gleichen Methode, die StartCoroutine aufrufen – user3836982

+0

Ist es für Sie möglich, den Code auf eine andere Methode zu verschieben? Sie können Ihren Zugriffscode auf den Rückruf zurücksetzen, den Sie haben, wenn Sie auf lokale Variablen zugreifen müssen. Kannst du uns genau sagen, was du mit "final" machen willst? Die erste Methode, die ich angegeben habe, funktioniert nicht in der Startmethode, die zweite dagegen. – EvilTak