Ich arbeite an einem Multiplattform-Projekt, wo ich viele Steuerelemente dynamisch als Ergebnis einiger wichtiger Berechnungen erstellen muss. Wenn ich die Bedingungen ändere, muss ich alle dynamisch erstellten Steuerelemente entfernen und die Neuberechnungen vornehmen und schließlich die Steuerelemente erneut erstellen.Dynamische Kontrollen gibt Segmentierung Fehler (11)
Ich handle dies, indem Sie zuerst dynamisch eine TScrollBox (iOFPLayout) auf einem TTabItem erstellen. Ich verschiebe die vordefinierte Kopfzeile TToolBar von der TTabItem in die TScrollBox, indem ich deren Eltern ändern. Dann erstelle ich Arrays von TLabel, TEdit und TButton Controls auf der TScrollBox. (Ich muss mit den dynamisch erstellten Steuerelementen im Code interagieren) Dieser Teil funktioniert auf allen Plattformen einwandfrei. Wenn ich die Steuerelemente entferne benutze ich den folgenden Code.
Auf Windows x86, x64 und OS X scheint es gut zu funktionieren. Unter Android funktioniert es einwandfrei, wenn die TScrollBox zum ersten Mal erstellt und mit dynamisch erstellten Steuerelementen gefüllt wird. Nachdem die TScrollBox entfernt und neu erstellt wurde, erhalte ich einen Fehler "Zugriffsverletzung" oder "Segmentierungsfehler (11)" an einem zufälligen Punkt, wenn die dynamischen Arrays von TLabel-Steuerelementen oberhalb der TScrollBox erstellt werden.
Ich habe das Gefühl, dass dies mit ARC zu tun hat. Ich habe alles über ARC gelesen und jeden Vorschlag, den ich finden kann, getestet, aber nichts scheint zu funktionieren. Sieht jemand was falsch ist?
Hier ist ein vollständiges minimales Arbeitsbeispiel.
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' ??? Warum??? –
Ich habe Application.ProcessMessages nur hinzugefügt, um zu sehen, dass die Steuerelemente während des Debuggens entfernt werden. – TheAviator
Wird von uns erwartet, dass Sie versuchen, Ihr Programm anhand Ihrer Beschreibung neu zu erstellen? Ich bezweifle, dass irgendjemand das tun wird. Können wir nicht einen [MCVE] haben? –