Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi在Android上从表单中删除FireMonkey元素_Delphi_Firemonkey_Delphi Xe7_Delphi 10 Seattle_Delphi 10.1 Berlin - Fatal编程技术网

Delphi在Android上从表单中删除FireMonkey元素

Delphi在Android上从表单中删除FireMonkey元素,delphi,firemonkey,delphi-xe7,delphi-10-seattle,delphi-10.1-berlin,Delphi,Firemonkey,Delphi Xe7,Delphi 10 Seattle,Delphi 10.1 Berlin,我在OnShow事件中使用此代码在表单上创建了一个元素: procedure TForm4.FormShow(Sender: TObject); var VertScrollLink:TVertScrollBox; begin VertScrollLink := TVertScrollBox.Create(form4); VertScrollLink.Align := TAlignLayout.Client; VertScrollLink.Parent := form4; end

我在
OnShow
事件中使用此代码在表单上创建了一个元素:

procedure TForm4.FormShow(Sender: TObject);
var
  VertScrollLink:TVertScrollBox;
begin
  VertScrollLink := TVertScrollBox.Create(form4);
  VertScrollLink.Align := TAlignLayout.Client;
  VertScrollLink.Parent := form4;
end;
在某些操作中,我需要动态删除布局:

for LIndex := form4.ComponentCount-1 downto 0 do
begin
  if (form4.Components[LIndex].ToString='TVertScrollBox') then
  begin
    //showmessage(form4.Components[LIndex].ToString);
    form4.Components[LIndex].Free;
  end;
end;
这段代码在Windows上运行良好,但在Android上不会删除任何内容。

原因是在移动平台(iOS和Android)上,但在桌面平台(Windows和OSX)上则不行。您的
Free()
实际上是一个no-op,因为从
Components[]
属性访问组件将增加其引用计数,然后
Free()
将减少它(事实上,编译器应该发出代码无效的警告)。组件仍然有对它的活动引用(其
所有者
父级
),因此它实际上没有被释放

如果要强制释放组件,需要调用它,例如:

for LIndex := form4.ComponentCount-1 downto 0 do
begin
  if form4.Components[LIndex] is TVertScrollBox then
  begin
    form4.Components[LIndex].DisposeOf;
  end;
end;
或者,移除活动参考,让ARC正常处理破坏:

var
  VertScrollLink: TVertScrollBox;
  LIndex: Integer;
begin
  ...
  for LIndex := form4.ComponentCount-1 downto 0 do
  begin
    if form4.Components[LIndex] is TVertScrollBox then
    begin
      VertScrollLink := TVertScrollBox(form4.Components[LIndex]);
      VertScrollLink.Parent := nil;
      VertScrollLink.Owner.RemoveComponent(VertScrollLink);
      VertScrollLink := nil;
    end;
  end;
  ...
end;

所说的,你可以考虑跟踪你创建的组件,这样你就不需要使用一个循环来找到它:

type
  TForm4 = class(TForm)
    procedure FormShow(Sender: TObject);
    ...
  private
    VertScrollLink: TVertScrollBox;
    ...
  end;

procedure TForm4.FormShow(Sender: TObject);
begin
  VertScrollLink := TVertScrollBox.Create(Self);
  VertScrollLink.Align := TAlignLayout.Client;
  VertScrollLink.Parent := Self;
end;


电弧烧着你了。值得一读。ToString是一种奇怪的类型测试方法。这不是PHP。使用
is
操作符。您没有使用XE。我删除了那个标记。@DavidHeffernan是的,我也使用PHP:)我将行
if(form4.Components[LIndex].ToString='TVertScrollBox')更改为
if(form4.Components[LIndex]是TVertScrollBox),然后
没有更改!!问题似乎出现在
form4.Components[LIndex].Free!!!是的,我知道。ARC是伤害你的东西。我就是这么说的。为什么你会期望免费在ARC上做任何事情。您了解ARC吗?为什么没有在delphi本地帮助中记录ARC@事实上是这样。至少在最近的版本中。例如,在10.0西雅图,这是ARC的本地帮助主题:
mk:@MSITStore:C:\Program%20Files\Embarcadero\Studio\17.0\help\Doc\topics.chm::/Automatic\u Reference\u Counting\u in_Delphi\u Mobile\u Compilers.htm
begin
  ...
  if Assigned(VertScrollLink) then
  begin
    VertScrollLink.DisposeOf;
    { or:
    VertScrollLink.Parent := nil;
    VertScrollLink.Owner.RemoveComponent(VertScrollLink);
    }
    VertScrollLink := nil;
  end;
  ...
end;