6

特定の関数を一度だけトリガーしたいことがよくありますが、繰り返し呼び出される別の関数内からトリガーする必要があります。たとえば、後で使用するために何かのスナップショットを作成します。私は通常、グローバルブール値を設定してそれを行います。

私がやっている方法が実際に最善の方法であるかどうか疑問に思っていますか?

グローバル変数は良くない、グローバル ブール変数はさらに悪いと読んだことを思い出すようです。

とにかく、これは私が通常、特定のメソッドを一度だけトリガーする方法です。

私の最初の変数セットでは...

private var myStatus:Boolean = false;

そして、よく呼び出される関数内で...

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

私にはかなり論理的に思えますが、それは正しいことですか?

更新:まあ、あなたの答えから学んだことに基づいて、グローバルブール変数をチェックする代わりに、まず XML ノードが存在するかどうかをチェックします (ディスクへの書き込みが発生する前に、XML 構造内に画像を保存しています)。そうでない場合は、base64 でエンコードされた画像データを含む新しいノードを追加します。後で必要に応じてユーザーが編集した画像データで空白の画像を上書きできるように、ブール値のフラグを設定します。それは完全に機能します。ご協力ありがとうございました!

また、特定の状況でその特定の (スレッドセーフでない) システムを使用することについて、より快適に感じるようになりました。

4

7 に答える 7

7

関数を呼び出すとき、それはあなたがそれを与える引数でそれがすることを期待することをするべきです。まったく同じ方法で関数を2回呼び出す場合、その関数が同じ結果をもたらすか、同じことを行うことを期待する必要があります。

このcall-once依存関係を、関数を何度も呼び出すロジックに移動することをお勧めします。関数を1回だけ呼び出す必要がある場合は、1回だけ呼び出します。または、関数に別の引数を渡して、別のことをしていることを示します。

于 2008-12-09T23:17:57.307 に答える
5

それは本当にあなたが何を意味するかによって異なります。コードが複数のスレッドから呼び出される場合、競合状態が発生し、doMyFunction何度も呼び出される可能性があります。これは、複数のスレッドが をチェックmyStatusし、それが false であることを確認してから、 を呼び出す可能性があるためdoMyFunctionです。最初に変数を設定することで、状況を少し改善できます。

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

しかし、それは問題の可能性を狭めるだけで、問題をなくすわけではありません。

競合状態を解消するには、ロックが必要です。

于 2008-12-09T23:06:15.867 に答える
4

C / C ++では、通常、次のような静的変数を使用して、カプセル化された1回だけdoMyFunction()が呼び出されるという事実を維持できます。

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

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

これにより、グローバルの使用は回避されますが、同じ効果があり、静的変数は関連する場所で正しく宣言されるため、何が起こっているのかが明確になります。これはスレッドセーフではないため、スレッドがある場合はロックが必要になることに注意してください。

于 2008-12-09T23:09:57.760 に答える
2

スレッドセーフではありません。それはあなたにとって重要ではないかもしれませんが、あなたは「言語に依存しない」と言いました。おそらく、Java用の汎用ライブラリでこのパターンを使用したくないでしょう。

利用可能な選択肢は言語に大きく依存するため、これは言語に依存しない方法で答えるのは難しい質問です。たとえば、POSIXでは、スレッドセーフが必要な場合はpthread_onceがあります。Cでは、そのブール値をグローバルスコープから外すための静的ローカル変数があります。どのオブジェクト指向言語でも、後で使用するために「何か」のスナップショットを取得する場合は、フラグを格納できる「何か」(またはスナップショット)に対応する適切なオブジェクトが存在する可能性があります。

于 2008-12-09T23:09:41.507 に答える
0

Perl 5.10 以降では、state変数を使用します。

use 5.010;

sub test{
  state $once = 1;

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

test for 1..5;

出力

最初
最初ではない
最初ではない
最初ではない
最初ではない
于 2008-12-10T20:01:27.937 に答える
0

他に方法はありません。これを改善する方法について頭に浮かぶ唯一のことは、スレッドセーフです。ただし、関数を呼び出すスレッドが複数ある場合にのみ必要です。

于 2008-12-09T23:06:13.527 に答える
0

ここでのアプローチに問題はありません。常に「正しい」ものがあるとは限らないことに注意してください...明らかに間違っているものがありますが、何が正しいかは主観的であり、システムの要件に基づいて劇的に異なる場合もあります。

于 2008-12-09T23:02:28.493 に答える