gpt4 book ai didi

android - 在 Android 中释放动态创建的控件

转载 作者:行者123 更新时间:2023-12-05 00:11:02 25 4
gpt4 key购买 nike

在我的 Firemonkey 多平台应用程序中,我动态创建了一些控件。使用后,我会销毁它们。

在 Windows 中,这个动态创建和销毁的进程没有问题。但是,在 Android 中,下面的代码似乎不会破坏控件,因为会弹出一个错误提示控件已经存在(当我尝试重新创建控件时,我确实看到旧控件仍然存在)。

我如何确保控件在 Android(和/或 iOS - 我认为它与 iOS 类似)中被正确销毁?

for i := oParentRect.ControlsCount-1 downto 0 do
begin
oControl := oParentRect.Controls[i];
if (oControl is TText)
or (oControl is TEdit)
then
begin
FreeAndNil( oControl );
// I have also tried oControl.Free;
end;
end;

最佳答案

在 RAD Studio 10.4 之前,Delphi 使用 ARC (Automatic Reference Counting)用于 iOS 和 Android 平台上的对象生命周期管理。在 ARC 下,TObject.Free()FreeAndNil() 的行为与您预期的不同。它们被编译器翻译成纯粹的 nil 赋值,减少对象的引用计数。一个对象在其引用计数降为 0 之前不会被释放。

在您的示例中,所讨论的对象有多个引用(在 Controls[] 列表和 oControl 变量中),因此 FreeAndNil( ) 没有达到预期的效果,因为它只是将 oControl 变量设置为 nil 而不是从 Controls[] 列表中删除对象。换句话说,您的示例实际上与以下示例相同:

for i := oParentRect.ControlsCount-1 downto 0 do
begin
oControl := oParentRect.Controls[i]; // <-- increments refcnt
if (oControl is TText) or (oControl is TEdit) then
begin
//FreeAndNil( oControl );
oControl := nil; // <-- decrements refcnt
end;
end;

如果你真的想在 ARC 下编码时立即销毁一个对象,你需要使用 TObject.DisposeOf()相反,例如:

for i := oParentRect.ControlsCount-1 downto 0 do
begin
oControl := oParentRect.Controls[i]; // <-- increments refcnt
if (oControl is TText) or (oControl is TEdit) then
begin
//FreeAndNil( oControl );
oControl.DisposeOf; // <-- destroys object, but does not free its memory yet
oControl := nil; // <-- decrements refcnt
end;
end;

在这种模型下,当一个对象被“处置”时,它的析构函数会立即被调用,但它的底层内存块还没有被释放。引用计数仍然发生在 block 上。该对象位于 "disposed" 中状态,直到它的引用计数降为 0,然后释放内存块。不再调用析构函数。

此行为记录在 Embarcadero 的 DocWiki 上:The Free and Dispose Of methods under ARC

现在,话虽如此,在 RAD Studio 10.4 中,Embarcadero has removed object ARC handling completely ,回到传统的内存管理模型(他们现在称之为“统一内存管理”)。在这种情况下,TObject.Free()FreeAndNil() 现在的行为与它们在非移动平台上的行为一样,但现在在所有平台上都是一样的。因此,您的原始代码现在将按预期工作,您无需在 10.4 之后切换到 TObject.DisposeOf()(不过,如果您愿意,可以,它的行为与 完全相同TObject.Free(),如果你需要支持 10.3 及更早版本,给你想要的效果)。

关于android - 在 Android 中释放动态创建的控件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62540072/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com