随着Delphi 10.4去掉了ARC,统一移动平台与桌面平台的内存管理,那对于释放对象,有什么变化呢?
先看看10.4的代码:
procedure TObject.Free;
begin
// under ARC, this method isn't actually called since the compiler translates
// the call to be a mere nil assignment to the instance variable, which then calls _InstClear
{$IFNDEF AUTOREFCOUNT}
if Self <> nil then
Destroy;
{$ENDIF}
end;
procedure TObject.DisposeOf;
type
TDestructorProc = procedure (Instance: Pointer; OuterMost: ShortInt);
begin
{$IFDEF AUTOREFCOUNT}
if Self <> nil then
begin
Self.__ObjAddRef; // Ensure the instance remains alive throughout the disposal process
try
if __SetDisposed(Self) then
begin
_BeforeDestruction(Self, 1);
TDestructorProc(PPointer(PByte(PPointer(Self)^) + vmtDestroy)^)(Self, 0);
end;
finally
Self.__ObjRelease; // This will deallocate the instance if the above process cleared all other references.
end;
end;
{$ELSE}
Free;
{$ENDIF}
end;
可以清楚的看到,在DisposeOf中,如果没有定义AUTOREFCOUNT编译变量,则直接调用Free方法。由于去掉ARC,AUTOREFCOUNT不再定义,所以调用DisposeOf,就是调用Free。现在可以忘记DisposeOf了,所有平台释放对象,就用Free。
接下来,再看看FreeAndNil方法:
procedure FreeAndNil(const [ref] Obj: TObject);
{$IF not Defined(AUTOREFCOUNT)}
var
Temp: TObject;
begin
Temp := Obj;
TObject(Pointer(@Obj)^) := nil;
Temp.Free;
end;
{$ELSE}
begin
Obj := nil;
end;
{$ENDIF}
这个方法,同样使用了AUTOREFCOUNT编译变量。
为了验证移动平台下,是否定义了AUTOREFCOUNT,笔者做了个测试代码:
procedure TForm1.FormCreate(Sender: TObject);
begin
{$IFDEF AUTOREFCOUNT}
Text1.Text:='AUTOREFCOUNT';
{$ELSE}
Text1.Text:='Not Defined AUTOREFCOUNT';
{$ENDIF}
end;
事实证明,在android运行时,显示Not Defined AUTOREFCOUNT。没有定义AUTOREFCOUNT,你可按这个去读上面的代码了!