終わることのない変更対応?

例えば以下のようなソースがあったとしましょう。

procedure TForm1.Edit1Change(Sender: TObject);
begin
  Edit1.text := Edit1.Text + 'a';
end;

Edit1 の Text が '' に変更されたとすると、

  1. 変更されたので Edit1Change が呼ばれ Edit1.Text := '' + 'a'; が実行される。
  2. 変更されたので Edit1Change が呼ばれ Edit1.Text := 'a' + 'a'; が実行される。
  3. 変更されたので Edit1Change が呼ばれ Edit1.Text := 'aa' + 'a'; が実行される。
  4. 変更されたので Edit1Change が呼ばれ Edit1.Text := 'aaa' + 'a'; が実行される。
  5. ・・・・・・・・・
  6. Stack overflow が起きる。

と、いうように暴走します。

このように OnChange イベントの中では良く考えて変更を行わないと永久ループにはまり込みます。
これはベースケースのない再帰関数が、間接的に行われているようなものです。

これを避けるには、以下のようにすれば一発です。

procedure TForm1.Edit1Change(Sender: TObject);
begin
  Edit1.OnChange := nil; 
  Edit1.Text := Edit1.Text + 'a';
  Edit1.OnChange := Edit1Change; 
end;

一時的に、無効にすれば問題なしということです。

しかし、使い道あるのだろうか、こんな知識・・・・。


Return index page