Delphi TCheckListBox获取我的对象

Delphi TCheckListBox获取我的对象,delphi,object,types,Delphi,Object,Types,如果获取已定义的类型对象,我会遇到问题。 我需要从列表框中获取变量定义对象 我的数据类型: type TObjectData = class Id: Integer; DataType: String; end; TProjektInfo = record Id: Integer; Nazev: String; end; TReportSelect = record Count: Integer; Zakazka_Id: Int

如果获取已定义的类型对象,我会遇到问题。 我需要从列表框中获取变量定义对象

我的数据类型:

type
  TObjectData = class
    Id: Integer;
    DataType: String;
  end;
  TProjektInfo = record
    Id: Integer;
    Nazev: String;
  end;
  TReportSelect = record
    Count: Integer;
    Zakazka_Id: Integer;
    Singles: Array of TProjektInfo;
    Multies: Array of TProjektInfo;
  end;
填写列表框的步骤:

procedure TReportMain.VykresyFillProjectsList();
var
  I,Id: Integer;
  Nazev: String;
  ItemData: TObjectData;
begin
  VykresyProjectsListSections.Items.BeginUpdate;
  VykresyProjectsListSections.Items.Clear;

  for I := Low(ReportSelect.Singles) to High(ReportSelect.Singles) do
  begin

    Id := ReportSelect.Singles[I].Id;
    Nazev := ReportSelect.Singles[I].Nazev;

    ItemData := TObjectData.Create;
    ItemData.Id := Id;
    ItemData.DataType := 'single';

    VykresyProjectsListSections.Items.AddObject(Nazev, TObject(ItemData));
    ItemData.Free;
  end;

  for I := Low(ReportSelect.Multies) to High(ReportSelect.Multies) do
  begin

    Id := ReportSelect.Multies[I].Id;
    Nazev := ReportSelect.Multies[I].Nazev;

    ItemData := TObjectData.Create;
    ItemData.Id := Id;
    ItemData.DataType := 'multi';

    VykresyProjectsListSections.Items.AddObject(Nazev, TObject(ItemData));
    ItemData.Free;
  end;

  VykresyProjectsListSections.Items.EndUpdate;
end;
单击获取我的数据类型对象时的My button事件(注释的位置错误):

procedure TReportMain.btnexportprojects单击(发送方:TObject);
变量
ItemData:TObjectData;
纳泽夫:弦;
I:整数;
开始
ItemData:=TObjectData.Create;
对于I:=0到VykresyProjectsListSections.Count-1 do
开始
如果VykresyProjectsListSections.Checked[I],则
开始

ItemData:=TObjectData(VykresyProjectsListSections.Items.Objects[I]);// 发生在您身上的可能是访问权限冲突

您试图访问的变量未定义,因为您已经释放了该变量所指向的对象

在上面的代码中,
ItemData
对象总是在添加到列表后被释放

当清除或释放列表时,必须编写一些代码来释放对象

这可以在表单的
ondestory
事件中完成:

procedure TReportMain.FormDestroy(Sender: TObject);
var
  i: Integer;
begin
  for i := VykresyProjectsListSections.Items.Count-1 downto 0 do begin
    VykresyProjectsListSections.Items.Objects[i].Free;
    VykresyProjectsListSections.Delete(i);
  end;

  VykresyProjectsListSections.Free;//free the list if not owned by the application
end;

作为旁注,您可以测试
TCheckListBox
元素是否被选中,如下所示:

var
  i: Integer;
begin
  for i := 0 to VykresyProjectsListSections.Items.Count-1 do begin
    if VykresyProjectsListSections.State[i] = cbChecked then
      //do your stuff
  end;
end;

您正在
AddObject()
之后调用
ItemData.Free
。这是错误的,因为对象将不再有效


这将在以后访问
复选框中的对象时导致错误

您说这是错误的,但不是为什么它是错误的。请解释一下。我们也不知道你的目标平台是什么,也不知道arc是否处于活动状态。评论在哪里显示访问冲突。行:ItemData:=TObjectData(VykresyProjectsListSections.Items.Objects[I]);我不知道为什么。如果你能提供我要求的其他细节,那会有帮助的。在问题编辑而不是评论中这样做。对不起,我是初学者。我的英语不专业。你在
AddObject()
之后调用
ItemData.Free
。这是错误的,因为对象将不再有效。然而,这并不能解决我的情况。我需要检查列表中的对象。@LukášVlček这是一个你没有问的问题。上述情况可能无法解决许多其他情况。目前我甚至不知道VykresyProjectsListSections是什么类型的组件。你可以考虑编辑你的问题,如果你想增加更多的细节,你的答案帮助了我。我明白,如果我想使用它,我不能释放该对象。谢谢,如果ARC正在运行该怎么办?在ARC下,设置对
nil
的引用与调用
Free
相同
DisposeOf
强制析构函数运行。但如果使用ARC I,则不会guess@DavidHeffernan,即使是这样,这仍然不是一个好的做法。我并不反对。我只希望提问者能更关心这个问题。
var
  i: Integer;
begin
  for i := 0 to VykresyProjectsListSections.Items.Count-1 do begin
    if VykresyProjectsListSections.State[i] = cbChecked then
      //do your stuff
  end;
end;