2017-05-23 5 views
0

Ich habe ein wenig mit dem Löschen von struct aus meinem TArray von structs.Meine Struktur enthält AudioComponent und float.I wurde Array.RemoveAt (index), aber was ich davon bekam nur die Hälfte meiner Struktur entfernt , das ist AudioComponent. Warum ist das? Meine Funktionselemente Entfernen sieht wie folgt aus:RemoveAt von StructArray Ue4

void RemoveArrayElement(UAudioComponent AudioComponent) 
{ 
    for(int i=0; i<Array.Num(); i++) 
    { 
     if(AudioComponent == Array[i].AudioComponent) 
     { 
      Array.RemoveAt(i); 
     } 
    } 
} 

Was will ich vollständig zu erreichen, zu löschen Index, AudioComponent mit seinen Schwimmer.

+1

Was meinst du mit * "Entfernen der Hälfte meiner Struktur" *? Ich verstehe nicht, wie Sie die Hälfte einer Struktur entfernen oder wie dies sich manifestiert (oder wie Sie es sehen) – UnholySheep

+0

Nehmen wir an Array [0] = Stuct (AudioComponent0, float0). Nachdem ich Array.RemoveAt (0) verwende, was ich bekomme ist Array [0] = Stuct (einige ungültige Wert, float0). – Avengar

+0

Also ändert sich die Größe des Arrays nicht und die restlichen Elemente in 'Array' werden nicht" vorwärts "verschoben? – UnholySheep

Antwort

0

Es gibt einige Probleme mit Ihrem Code. Wie andere in Kommentaren erwähnt, sollten Sie Zeiger verwenden. Und wenn ich mich nicht irre, Sie sind nicht zu verwenden Konstruktion wie diese erlaubt:

UPROPERTY() 
    TArray<UAudioComponent> invalidArray; 

sollten Sie UPROPERTY Makro verwenden, sonst wird Ihre Eigenschaften könnten und wahrscheinlich wird Müll gesammelt. UPROPERTY wiki.

Als nächstes ändern Sie das Array, über das Sie iterieren. Ich schrieb einige Ansätze, lassen Sie uns auf sie schauen:

void RemoveArrayElement(UAudioComponent* AudioComponent) 
{ 
    TArray<UAudioComponent*> audioArray; // array will be initialized somewhere else, this is for demo purpose. 


    // you always should check your pointers for validity 
    if (!AudioComponent || !AudioComponent->IsValidLowLevel() || AudioComponent->IsPendingKill()) 
     return; 


    // Correct approach 1 (multiple): 
    TQueue<UAudioComponent*> toDelete; 

    for (int i = 0; i < audioArray.Num(); i++) 
    { 
     auto item = audioArray[i]; 
     if (AudioComponent == item || true) // we simulate another condition for multiselect 
     { 
      toDelete.Enqueue(item); 
     } 
    } 

    // better approach for iteration: 
    for (auto item : audioArray) 
     if (item == AudioComponent || true) // we simulate another condition for multiselect 
      toDelete.Enqueue(item); 


    // finalize deletion in approach 1 
    UAudioComponent* deleteItem; 
    while (toDelete.Dequeue(deleteItem)) 
     audioArray.Remove(deleteItem); 




    // almost correct approach 2 (single) : 
    UAudioComponent* foundItem; 

    for (auto item : audioArray) 
     if (item == AudioComponent) 
     { 
      foundItem = item; 
      break;   // we can skip rest - but we must be sure, that items were added to collection using AddUnique(...) 
     } 

    if (foundItem) 
     audioArray.Remove(foundItem); 


    // correct and the best - approach 3 (single) 

    audioArray.Remove(AudioComponent); 
} 
+0

Ich zitiere von Ihrem Wiki-Link: "Nicht-UPROPERTY-Variablen werden vom GC-System nicht gezählt." So wird nichts Müll gesammelt werden, wenn es kein UPROPERTY ist. – Shiro

0

Denken Sie daran, dass der Vergleich zweier Objekte nicht unbedingt zum erwarteten Ergebnis der Gleichheit führt. Mit dem Operator == wird eine Funktion ausgeführt (bool operator==(L, R);), die angibt, was passieren soll. Wenn Sie also den Operator == nicht überladen haben, wissen Sie nicht, was die Verwendung des Operators ergeben würde, es sei denn, Sie sehen sich den Quellcode an, in dem er definiert ist. Da Sie die genaue Audiokomponente und nicht eine Instanz davon entfernen möchten, die gleich aussieht, möchten Sie Zeiger in Ihrem Array verwenden. Das hilft auch die Leistung, da Sie nicht die gesamte Komponente beim Aufruf von RemoveArrayElement(...);, sondern einen einzigen Zeiger kopieren. Auch wenn zwei identische Audiokomponenten in dem Array gespeichert sind und sie sich bei Index a und a + 1 befinden, würde das Entfernen der Audiokomponente bei Index a bei der nächsten Iteration Ihre zweite Audiokomponente überspringen, da alle oberen Indizes um eins dekrementiert werden.

Verwandte Themen