在 RAD Studio 10.4 中,Embarcadero 决定在其移动平台上删除 ARC for object lifetime management。
What's New in RAD Studio 10.4 Sydney
统一内存管理
-
Delphi 内存管理现在在所有受支持的平台(移动、桌面和服务器)上统一 - 使用对象内存管理的经典实现。与自动引用计数 (ARC) 相比,这为现有代码提供了更好的兼容性,并且为组件、库和最终用户应用程序提供了更简单的编码。 ARC 模型仍然用于所有平台的字符串管理和接口类型引用。
-
对于 C++,此更改意味着在 C++ 中创建和删除 Delphi 风格的类就像任何堆分配的 C++ 类一样遵循正常的内存管理,从而显着降低了复杂性。
在所有 Delphi 编译器版本和平台上检测何时使用 ARC 对象生命周期管理的正确方法是使用 {$IFDEF AUTOREFCOUNT}。 BoxPrimitives.pas 单元中甚至提到了这一点:
该类仅供 AUTOREFCOUNT 编译器使用
例如:
{$ifdef AUTOREFCOUNT}
uses BoxPrimitives;
{$endif}
{$ifdef AUTOREFCOUNT}
cbGender.Items.AddObject('Male', TBoxInteger(1));
cbGender.Items.AddObject('Female', TBoxInteger(0));
{$else}
cbGender.Items.AddObject('Male', TObject(1));
cbGender.Items.AddObject('Female', TObject(0));
{$endif}
...
var Value: Integer;
{$ifdef AUTOREFCOUNT}
Value := TBoxInteger(cbGender.Items.Objects[index]);
{$else}
Value := Integer(cbGender.Items.Objects[index]);
{$endif}
话虽如此,我可能会更进一步,通过编辑BoxPrimitives.pas 以用{$IFDEF AUTOREFCOUNT} ... {$ELSE} ... {$ENDIF} 包围其代码,然后在{ELSE} 部分中将TBoxInteger(和其他类型)定义为简单别名,例如:
interface
{$ifdef AUTOREFCOUNT}
uses
Classes, Types, Generics.Defaults;
type
TRSBoxPrimitive<T> = class(TObject)
...
end;
TBoxInteger = TRSBoxPrimitive<Integer>;
TUnboxInteger = TBoxInteger;
...
{$else}
type
TBoxInteger = TObject;
TUnboxInteger = Integer;
...
{$endif}
implementation
{$ifdef AUTOREFCOUNT}
...
{$endif}
end.
那么你根本不需要{$IFDEF}你的AddObject()调用,只需在所有平台上无条件地使用TBoxInteger和TUnboxInteger,例如:
// look ma, no IFDEF's!
uses BoxPrimitives;
cbGender.Items.AddObject('Male', TBoxInteger(1));
cbGender.Items.AddObject('Female', TBoxInteger(0));
...
var Value: Integer;
Value := TUnboxInteger(cbGender.Items.Objects[index]);