Wie eine Funktion einmal auszulösen, und nur einmal ...?

stimmen
6

Ich mag oft nur einmal eine bestimmte Funktion auszulösen, aber ich brauche es auslösen innerhalb einer anderen Funktion, die immer wieder aufgerufen wird. Zum Beispiel einen Schnappschuss von etwas für den späteren Gebrauch nehmen. Ich mache es in der Regel durch eine globale boolean Einstellung.

Ich frage mich, ob die Art, wie ich es tun, ist eigentlich beste Weg?

Ich scheine zu lesen, daran zu erinnern, dass die globalen Variablen sind schlecht, und die globale boolean Variablen ist noch schlimmer!

Wie auch immer, das ist, wie ich erreichen in der Regel nur einmal eine bestimmte Methode Auslösung:

In meinem ersten Satz von Variablen ...

private var myStatus:Boolean = false;

Dann innerhalb der Funktion, die oft aufgerufen wird ...

if (!myStatus) {
    doMyFunction();
    myStatus = true;
}

Es scheint ziemlich logisch für mich, aber es ist das Richtige ?

UPDATE : Nun, auf das, was ich aus Ihren Antworten gelernt, anstatt eine globale boolean Variable überprüft, überprüfe ich nun zuerst , ob der XML - Knoten vorhanden ist (ich bin Speichern der Bilder in einer XML - Struktur vor jedem Schreiben auf die Festplatte erfolgt), und, wenn es nicht der Fall ist, dann fügen sie I einen neuen Knoten mit den Bilddaten codiert Base64. Ich noch ein boolesches Flag , so dass später eingestellt auf mich das leere Bild mit Benutzer editierten Bilddaten überschrieben werden kann , wenn nötig. Es funktioniert perfekt. Vielen Dank für Ihre Hilfe!

Ich fühle mich auch jetzt noch komfortabler über diese bestimmte (Thread unsichere) System in bestimmten Situationen verwendet wird.

Veröffentlicht am 09/12/2008 um 23:59
quelle vom benutzer
In anderen Sprachen...                            


7 antworten

stimmen
7

Wenn Sie eine Funktion aufrufen, sollte es tun, was Sie es mit den Argumenten geben Sie es zu tun erwarten. Wenn Sie eine Funktion zweimal aufrufen genau die gleiche Art und Weise sollten Sie diese Funktion erwarten Sie die gleichen Ergebnisse zu geben oder das gleiche zu tun.

Es ist wahrscheinlich besser, diesen Ruf einmal Abhängigkeit der Logik zu bewegen, die Ihre Funktion oft aufruft. Wenn Sie nur einmal brauchen die Funktion aufgerufen werden dann nur einmal anrufen. Alternativ können verschiedene Argumente an die Funktion übergeben, um anzuzeigen, dass Sie etwas anderes tun.

Beantwortet am 10/12/2008 um 00:17
quelle vom benutzer

stimmen
5

Es hängt wirklich von genau das, was Sie meinen. Wenn Ihr Code von mehr als einem Thread aufgerufen werden, dann haben Sie eine Race - Bedingung , die bedeuten könnte , dass doMyFunctionkönnte viele Male aufgerufen werden. Dies liegt daran , mehr als ein Thread könnte überprüfen myStatus, sieht , dass es falsch ist, dann rufen doMyFunction. Sie können durch Setzen der Variable die Situation ein wenig verbessern erste:

if (!myStatus) {
    myStatus = true;
    doMyFunction();
}

sondern dass nur das Fenster für Probleme verengt, es nicht beseitigen.

Um die Race-Bedingung zu beseitigen, müssen Sie eine Sperre.

Beantwortet am 10/12/2008 um 00:06
quelle vom benutzer

stimmen
4

In C / C ++ Sie in der Regel die Tatsache halten, dass doMyFunction () nur einmal verkapselt genannt wird durch eine statische Variable wie so verwenden:

void doMyFunction() {
     // gets called only once.
     // side effects go here.
}

void functionThatGetsCalledALot() {
    static bool called = false;
    if (!called) {
        doMyFunction();
        called = true;
    }
    // do more stuff
}

Dies vermeidet die Verwendung von Globals aber hat die gleiche Wirkung, und die statische var ist richtig erklärt, wo es relevant ist, so ist es klar, was los ist. Beachten Sie, dass dies nicht Thread-sicher, so dass Sie eine Sperre benötigen, wenn Sie Threads haben.

Beantwortet am 10/12/2008 um 00:09
quelle vom benutzer

stimmen
2

Es ist nicht Thread-sicher. Das mag nicht für Sie, aber du hast sagen „sprachunabhängig“: Sie wollen wahrscheinlich nicht dieses Muster in einem Universalbibliothek für Java verwenden.

Dies ist eine schwierige Frage in einer sprachunabhängig Art und Weise zu beantworten, da die zur Verfügung stehenden Alternativen sehr viel über die Sprache abhängen. Zum Beispiel auf POSIX du hast pthread_once, wenn Sie Thread-Sicherheit benötigen. In C haben Sie statische lokale Variablen haben, dass boolean, um aus dem globalen Bereich. In jeder OO-Sprache, wenn Sie einen Schnappschuss von „etwas“ für die späteren Gebrauch nehmen, dann könnte es ein geeignetes Objekt sein, entsprechend den „etwas“ (oder auf den Snapshot), die unter der Flagge speichern könnte.

Beantwortet am 10/12/2008 um 00:09
quelle vom benutzer

stimmen
0

In Perl 5.10 oder später würden Sie eine verwenden stateVariable.

use 5.010;

sub test{
  state $once = 1;

  if( $once ){
    $once = undef;
    say 'first';
  } else {
    say 'not first';
  }
}

test for 1..5;

Ausgänge

zuerst
nicht zuerst
nicht zuerst
nicht zuerst
nicht zuerst
Beantwortet am 10/12/2008 um 21:01
quelle vom benutzer

stimmen
0

Ich sehe keine andere Möglichkeit. Das einzige, was über den Sinn kommt, wie dies zu verbessern ist - Thread-Sicherheit. Aber das ist nur erforderlich, wenn Sie die Funktion mehrere Threads haben aufrufen.

Beantwortet am 10/12/2008 um 00:06
quelle vom benutzer

stimmen
0

Ich sehe nichts falsch mit Ihrem Ansatz hier. Denken Sie daran, es ist nicht immer die „richtige“ Sache ... es gibt auf jeden Fall falsch Dinge, aber was richtig ist subjektiv sein kann, und auch auf den Anforderungen des Systems dramatisch Basis verlassen kann.

Beantwortet am 10/12/2008 um 00:02
quelle vom benutzer

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more