发布后Delphi XE10.2表单不为零

sda*_*rle -1 forms delphi

我在Delphi中使用多年的技术已不再适用,因为我创建的表单在发布后不会设置为nil.这是一些示例代码:

type 
  TAboutForm = class(TForm);
  end;

function ShowAboutForm: TModalResult;
function ShowAboutForm2: TModalResult;

implementation

var
  FAboutForm: TAboutForm;

{$R *.dfm}

function AboutForm: TAboutForm;
begin
  if not Assigned(FAboutForm) then
    FAboutForm := TAboutForm.Create(Application);
  Result := FAboutForm;
end;

function ShowAboutForm: TModalResult;
begin
  with AboutForm do
    try
      Result := ShowModal;
    finally
      Release;
    end;
end;

function ShowAboutForm2: TModalResult;
var
  AAboutForm: TAboutForm;
begin
  AAboutForm := AboutForm;
    try
      Result := AAboutForm.ShowModal;
    finally
      AAboutForm.Release;
      AABoutForm := nil;
    end;
end;
Run Code Online (Sandbox Code Playgroud)

ShowAboutForm和ShowAboutForm2都没有第二次工作.两者都抛出访问冲突,因为任何一种方法都没有将FAboutForm设置为nil - 即使ShowAboutForm2显式地将局部变量设置为nil - 因此它不会在AboutForm中重新创建.我发现让代码工作的唯一方法是:

function ShowAboutForm3: TModalResult;
begin
  fAboutForm := AboutForm;
  try
    Result := fAboutForm.ShowModal;
  finally
    fAboutForm.Release;
    fAboutForm := nil;
  end;
Run Code Online (Sandbox Code Playgroud)

这是处理创建和发布表单的合适方式吗?除非直接引用已实现的var,否则为什么表单不会被释放?

Dal*_*kar 9

你的技术一直都被打破了.如果它曾经有效,那只是偶然的.

在第一个示例中,您只是发布表单,您永远不会将其全局引用设置为nil,因此它将指向表单对象实例所在的无效内存.

在第二个示例中,您将对表单对象的本地引用设置为nil,而不是稍后测试的全局引用.由于您正在测试的引用Assigned从未设置为nil,因此它也指向无效的内存.

变量(reference)仅表示指向真实对象所在的内存的指针.您可以拥有指向同一对象实例的多个指针.但是这些参考文献中的每一个都是独立的.如果您将其中一个设置为nil,或设置为任何其他值,则其他引用仍将指向之前指向的任何内容.

正如您已经发现的那样,真正的解决方案是将fAboutForm引用设置为nil,因为这是您正在测试的引用Assigned.


此外,由于您使用全局变量来保留引用并在AboutForm函数中分配该变量,因此您实际上不必再ShowAboutForm3使用它来分配它fAboutForm := AboutForm.

它对你的代码功能没有任何影响,它会起到同样的作用,但它有点乱.