私はいくつかの主要な計算の結果として動的にたくさんのコントロールを作成しなければならないマルチプラットフォームプロジェクトに取り組んでいます。条件を変更するときは、動的に作成されたすべてのコントロールを削除して、再計算を行い、最後にコントロールを再度作成する必要があります。ダイナミックコントロールはセグメント化エラーを発生させます。(11)
私はまず、TTabItemの上にTScrollBox(iOFPLayout)を動的に作成します。私は事前定義されたヘッダーTToolBarを、その親を変更することによって、TTabItemからTScrollBoxに移動します。次に、TScrollBoxにTLabel、TEdit、TButtonコントロールの配列を作成します。 (私はコードで動的に作成されたコントロールと対話する必要があります)この部分はすべてのプラットフォームで正常に動作します。コントロールを削除すると、以下のコードが使用されます。
Windows x86、x64、およびOS Xでは正常に動作しているようです。 AndroidではTScrollBoxが初めて作成され、動的に作成されたコントロールでいっぱいになります。 TScrollBoxが削除され、再作成された後、TLabelコントロールの動的配列がTScrollBoxの上に作成されると、ランダムアクセスポイントで「アクセス違反」または「セグメンテーションフォールト(11)」というエラーが発生します。
これはARCと関連があると感じています。私はARCに関するすべてのことを読んだことがありますが、私が見つけることができるすべての提案をテストしましたが、何も動作していないようです。誰が何が間違っているのを見ますか?
procedure TTabbedForm.RemoveOFP();
begin
// Move the ToolBar2 back to TabItem3 so it won’t get destroyed
ToolBar2.Parent := TabItem3;
if Assigned(iOFPLayout) then
begin
// iOFPLayout holds a lot of dynamically created controls
iOFPLayout.Release;
iOFPLayout.DisposeOf;
iOFPLayout := nil;
Application.ProcessMessages;
end;
end;
ここには完全な最小限の動作例があります。
unit Unit1;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls, FMX.Controls.Presentation, FMX.Layouts;
type
TMainForm = class(TForm)
ToolBar1: TToolBar;
Create: TButton;
Destroy: TButton;
procedure CreateClick(Sender: TObject);
procedure DestroyClick(Sender: TObject);
private
sb: TScrollBox;
lbl: array of TLabel;
end;
var
MainForm: TMainForm;
implementation
{$R *.fmx}
procedure TMainForm.CreateClick(Sender: TObject);
var
i: Integer;
begin
// Create a TScollBox on the MainForm
sb := TScrollBox.Create(Self);
sb.Align := TAlignLayout.Client;
sb.ShowScrollBars := True;
sb.Parent := MainForm;
// Set up the number of labels to put on sb
SetLength(lbl, 1000);
// Create these labels and set some properties
for i := Low(lbl) to High(lbl) do
begin
// On first run on Android devices this causes no problems.
// After DestroyClick has been run after the first CreateClick then
// I get "Access violation/Segmentation fault (11) here.
// It happens after about 800+ labels has been created.
lbl[i] := TLabel.Create(sb);
lbl[i].Text := 'Label ' + IntToStr(i);
lbl[i].Position.X := 10;
lbl[i].Position.Y := i * 20;
lbl[i].Parent := sb;
end;
end;
procedure TMainForm.DestroyClick(Sender: TObject);
begin
if Assigned(sb) then
begin
sb.Release;
sb.DisposeOf;
sb := nil;
end;
end;
end.
'Application.ProcessMessages' ???なぜ??? –
私はApplication.ProcessMessagesを追加して、デバッグ中にコントロールが削除されるのを見ました。 – TheAviator
あなたの説明からあなたのプログラムを作り直すことを期待していますか?私は誰もそれをすることを疑う。 [mcve]はできませんか? –