Delphi: TImage.Create引起访问冲突

4

我很抱歉提出这个新手问题,但是为什么我在下面的代码中(在“Create(SelectorForm);”行上)会得到“访问冲突”错误?我尝试将主窗体用作所有者,但没有任何区别。

var
  SelectorForm: TSelectorForm;
  ArrayOfImages: Array [1..10] of TImage;

implementation

procedure TSelectorForm.FormCreate(Sender: TObject);
var
  Loop: Byte;
begin
  for Loop := 1 to 10 do
  begin
    with ArrayOfImages[Loop] do
    begin
      Create(SelectorForm);
    end;
  end;
end;
2个回答

18
问题在于你实际上正在做这个:
var
  imageVariable: TImage;
begin
  imageVariable.Create (ParentForm);
end;

原代码有问题,因为“Create”方法被调用的变量尚未被赋值。

你应该这样做:

var
  imageVariable: TImage;
begin
  imageVariable := TImage.Create (ParentForm);
  try
    //use the object
  finally
    FreeAndNil (imageVariable);
  end;
end;

更具体地说,就是在你的代码中:

for Loop := 1 to 10 do
begin
  ArrayOfImages[Loop] := TImage.Create (Self);
end;

不要忘记释放对象

编辑:接受 @andiw 的评论并撤回释放对象的提示。 编辑2:接受 @Gerry 的评论并使用 Self 作为所有者。


在我看来,由于TImages被传递为它们的所有者,所以当SelectorForm被销毁时,它们将自动释放 - 或者我理解错了什么? - Andreas Wieland
@andiw:你是对的。如果你将表单指定为它们的所有者,就不需要释放这些对象。 - Hemant
3
TImage.Create(Self); 会更好。在表单类的方法中使用特定的表单实例变量几乎总是一个坏主意 - 如果有人使用另一个名称创建了一个实例,它将失败。 - Gerry Coll

0
以上代码存在很多问题。(首先不要像那样使用"With",不要使用Byte作为循环变量)
我的假设是您最终想要一个由TImage实例数组创建的表单作为父级。
因此,基于这个假设...您需要类似以下的代码(未经测试):
var
  ArrayOfImages: Array [0..9] of TImage;  
  i : integer;
begin
  for i := 0 to 9 do
  begin
    ArrayOfImages[i] := TImage.Create(theForm);
  end;

end;

现在请注意,当您完成使用数组时,您将负责清理它,您需要对每个图像实例调用free。

1
使用byte作为循环变量肯定不算问题。 - mghie
2
不,这只是一个风格问题。限制循环范围没有错,但“byte”通常是有意义的大小,我需要再花费几秒钟来思考为什么使用byte。 - Tim Jarvis
不,他不需要清理实例。theForm会处理它。而且这个数组是全局的。当单元完成时,它就会消失。 - Fabricio Araujo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接