DelphiXE5 iOSアプリ(iPhone,iPad)にて2つのフォームを作成し、フォーム①でボタン1をクリックするとフォーム②に動的にコントロールを配置し、フォーム②のボタンでFreeを行いCloseさせているのですが、さらにそこからフォーム①のボタン2をクリックすると、フォーム②にボタン1で作成したコントロールが残ります。
Release、Destroyだと一見動作しますが、その後、他の処理を行っているとエラーがでて動かなくなってしまいます。
DelphiにはRelease、Destroyは使わないように書かれておりますので、
対処法をご教授頂けますと幸いです。
フォーム①
unit freebug;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls,freebug2;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ private 宣言 }
public
{ public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.fmx}
procedure TForm1.Button1Click(Sender: TObject);
begin
Form2.Start1(Self);
Form2.Show;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
Form2.Start2(Self);
Form2.Show;
end;
end.
フォーム②
unit freebug2;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Edit,
FMX.StdCtrls, FMX.ListBox, FMX.Layouts, FMX.Memo;
type
TForm2 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ private 宣言 }
zEdit:TMemo;
zPanel:Tpanel;
public
{ public 宣言 }
procedure Start1(Sender: TObject);
procedure Start2(Sender: TObject);
end;
var
Form2: TForm2;
implementation
{$R *.fmx}
procedure TForm2.Button1Click(Sender: TObject);
begin
zPanel.Free;
Close;
end;
procedure TForm2.Start1(Sender: TObject);
begin
zPanel := TPanel.Create(Form2);
zPanel.Parent := Form2;
zEdit := TMemo.Create(Form2);
zEdit.Parent := zPanel;
zEdit.SetBounds(0, 0, 100, 50);
end;
procedure TForm2.Start2(Sender: TObject);
begin
zPanel := TPanel.Create(Form2);
zPanel.Parent := Form2;
zEdit := TMemo.Create(Form2);
zEdit.Parent := zPanel;
zEdit.SetBounds(100, 0, 100, 50);
zPanel.SetBounds(100, 100, 100, 50);
end;
end.
FireMonkeyとかまったく分かりませんが、VCL的感覚で申しますと、
> zEdit := TMemo.Create(Form2);
このTMemoはOwnerがForm2ですから、親コントロールのTPanelをFreeしても同時にFreeされません。
zEdit := TMemo.Create(zPanel);
このようにすれば、zPanelがFreeされるときにzEditもFreeされます。(VCLと同じならば、ですが!)
>DelphiにはRelease、Destroyは使わないように書かれておりますので、
どこに書いてあるんですか? 差し支えなければ教えてください。
Harryさんご教授ありがとうございます。
zEdit := TMemo.Create(zPanel);
に変更しましたがFreeされませんでした。
>どこに書いてあるんですか? 差し支えなければ教えてください。
Relaseはすみません。どこで見たのか分からなくなってしまいました。
記憶上では非推奨だったと認識しています。
Destroyは
http://docwiki.embarcadero.com/Libraries/XE4/ja/Bde.DBTables.TBatchMove.Destroy
に記載されていることから使用しない方が良いと思っていました。
自分の手元で確認できないのに、適当なことを言って済みませんでした。
ハッキリ言って私にはお手上げです。どなたか分かる方いませんか〜!
ヘルプを見てみましたが特にVCLと変わらず、TComponentはVCLと同一ですので、なぜ改善されないのか?です。
http://docwiki.embarcadero.com/Libraries/XE5/ja/FMX.Memo.TMemo.Create
これ、TPanelとTMemo、両方とも使える状態で残っちゃってるんですか?
で、、、なるべく一般的な書き方をしたほうがトラブルが少ないと思いますので、いくつかアドバイスをさせてください。
(懲りずに適当なこと言いますので、話半分でお願いします!)
・ 「フォーム①でボタン1をクリック」 → めっちゃ分かりにくいです。「Form1でButton1をクリック」と記述してください。
ついでに言うと、丸数字は混乱の元なので一切使わない方が良いですよ。(1)とかどうですか。
・ Form2のStart1、Start2メソッドについて。
現在、↓このようになってますが、
Form2.Start1(Self);
procedure TForm2.Start1(Sender: TObject);
引数が要らないなら、↓このように出来ます。さらに、括弧は省略してもかまいません。
Form2.Start1();
procedure TForm2.Start1();
・ いくつかちょっと書き直してみますね。ぜひやってみて欲しいです。
procedure TForm2.Button1Click(Sender: TObject);
begin
FreeAndNil(zPanel); // オブジェクトの変数を使い回すならFreeした後にnilを代入する。これにより、
// (1) nilならば空っぽであると判別できる。クラス内のオブジェクト変数の初期値はnilです。
// (2) 誤って何度もFreeしてしまうミスを防げる。nilをFreeしても、スルーされるだけなので。
Close;
end;
procedure TForm2.Start1();
begin
if Assigned(zPanel) then Exit; // zPanelが空っぽでない場合は処理しない。
zPanel := TPanel.Create(Self); // TForm2クラスのメソッドなのでSelfと書けばForm2と同義。
zPanel.Parent := Self;
zEdit := TMemo.Create(zPanel); // OwnerをTPanelにしておく。
zEdit.Parent := zPanel;
zEdit.SetBounds(0, 0, 100, 50);
end;
>Relaseはすみません。どこで見たのか分からなくなってしまいました。
RelaseはVCLとは何もかも異なるようですね。VCLではフォームはFreeでなくRelaseを使用せよ、とされています。
Destroyはクラスの内部で使うためのものですから、むやみに呼び出しちゃいけないのです。
お役に立てなくて残念ですが、上の落書きをご笑覧いただければと思います。
Harryさん。多くのご教授ありがとうございます。
今後の参考にさせて頂きます。
>これ、TPanelとTMemo、両方とも使える状態で残っちゃってるんですか?
使える状態で残ってしまうのです。
ご教示頂きました処理も試してみましたがやはり残ってしまいました。
とりあえずReleaseであれば残らなくなりますので、
その後のエラーの原因を探した方が良いかもしれないですね。
(今回のサンプルには載せてません)
ツイート | ![]() |