Bazı büyük hesaplamaların sonucu olarak dinamik olarak çok sayıda denetim oluşturmam gereken bir çoklu platform projesi üzerinde çalışıyorum. Koşulları değiştirirken, dinamik olarak oluşturulmuş tüm denetimleri kaldırmalı ve yeniden hesaplamaları yapmalı ve sonunda denetimleri yeniden oluşturmam gerekir.Dinamik denetimler, Segmentasyon hatası verir (11)
Bunu ilk olarak dinamik olarak bir TTabItem'in üstünde bir TScrollBox (iOFPLayout) oluşturun. Ön tanımlı üstbilgi TToolBar'ı, üst öğeyi değiştirerek TTabItem'den TScrollBox'a taşıyorum. Ardından TScrollBox'ta TLabel, TEdit ve TButton kontrol dizileri oluşturuyorum. (Kodda dinamik olarak oluşturulmuş kontrollerle etkileşime girmem gerekiyor) Bu bölüm tüm platformlarda iyi çalışıyor. Kontrolleri kaldırdığımda aşağıdaki kodu kullanıyorum.
Windows x86, x64 ve OS X'de iyi çalışıyor gibi görünüyor. Android'de TScrollBox ilk oluşturulduğunda ve dinamik olarak oluşturulmuş kontrollerle doldurulduğunda iyi çalışıyor. TScrollBox kaldırıldıktan ve yeniden oluşturulduktan sonra, TScrollBox'un üstünde TLabel denetimlerinin dinamik dizileri oluşturulduğunda rasgele bir noktada “Erişim İhlali” veya “Segmentasyon hatası (11)” hatası alıyorum.
Bunun ARC ile ilgili olduğunu hissediyorum. ARC ile ilgili her şeyi okudum ve bulabildiğim her şeyi test ettim ama hiçbir işe yaramadı. Herkes neyin yanlış olduğunu görüyor mu?
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;
İşte tam bir örnek çalışma örneği.
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' ??? Niye ya??? –
Sadece denetimleri hata ayıklama sırasında kaldırıldığını görmek için Application.ProcessMessages ekledim. – TheAviator
Programınızı açıklamanızdan yeniden oluşturmayı denememiz bekleniyor mu? Bunu yapacak biri olduğundan şüpheliyim. [Mcve] 'ye sahip olamaz mıyız? –