我想知道在调用New和Disposed时内部会发生什么.Delphi的帮助提供了一个合理的解释,但是如果一个人会写一个自己的New和Dispose,那该怎么办呢?哪个方法在内部调用两个方法还是全部组装?
我不打算写自己的New和Dispose.我对这两种方法的内部工作非常好奇.
New 执行以下操作:
GetMem.Dispose 颠倒了这个:
FreeMem.请注意这两个New和Dispose的内在功能.这意味着编译器具有额外的知识,并且能够根据所讨论的类型改变它们的实现方式.
例如,如果类型没有托管字段,则New优化为简单调用GetMem.如果类型具有托管字段,则New通过调用来实现,该调用System._New执行上述步骤.
实施Dispose方式大致相同.FreeMem对非托管类型的简单调用,以及对System._Dispose其他方式的调用.
现在,System._New实现如下:
function _New(Size: NativeInt; TypeInfo: Pointer): Pointer;
begin
GetMem(Result, Size);
if Result <> nil then
_Initialize(Result, TypeInfo);
end;
Run Code Online (Sandbox Code Playgroud)
请注意,PUREPASCAL为了简单起见,我刚刚展示了该变体.这个电话GetMem很简单.呼吁System._Initialize更多涉及.它使用TypeInfo参数来查找对象中包含的所有托管类型并初始化它们.这是一个递归过程,因为,例如,记录可能包含本身是结构类型的成员.您可以在RTL源中查看所有血腥细节.
至于System._Dispose它System._Finalize,然后调用FreeMem.而且System._Finalize是非常相似,System._Initialize不同的是它最终确定管理类型,而不是初始化它们.
长期以来,对于性能敏感的Delphi用户来说,这是一个bug,System._Initialize并且System._Finalize以运行时类型信息为基础以这种方式实现.这些类型在编译时是已知的,编译器可以编写为内联初始化和最终化,这将导致更好的性能.