如何在添加到Items.Objects []列表时保持接口对象不被删除?

时间:2014-09-04 17:59:53

标签: delphi

我有一个如此定义的接口对象(TStringList列表):

type
  IMyList = IArrayList<TStringList>;
  TMyList = TArrayList<TStringList>;

我在函数中为它创建实例并将它们返回给调用者。在这里我得到这样一个实例然后把它保存到TListBox.Items.Objects []属性供以后参考,然后显示它。想法是当有人点击TListBox条目时,我想从Objects []获取此列表并显示它。

procedure do_something;
var
  a_list : IMyList;
begin
  . . .
  a_list := get_some_data_in_a_list();
  // (1)
  listbox1.Items.Objects[n] := TMyList(a_list); // save ref in Items.Objects
  ShowList( a_list );
  . . .
end;

这里是列表框的onClick处理程序:

procedure TfrmMain.listbox1Click(Sender: TObject);
var
  n : integer;
  a_list : IMyList;
begin
  n := listbox1.ItemIndex;
  if (n < 0) then exit;
  a_list := IMyList(listbox1.Items.Objects[n]);  // (2)

  ShowList( listbox1.Items[n], a_list );
end;

问题是,在上面的第(2)行,a_listNIL。在将对象添加到Objects []属性后,界面正在破坏对象。

如果我在上面第(1)行添加:

a_list._AddRef;

然后在第(2)行a_list就像预期的那样出现。

这似乎是一个不应该是必要的黑客攻击,它可能是由于将项目添加到Objects []中而导致的,因为它的类型是IMyList,这是必需的。并非来自TObject,而TMyList是。

如果不诉诸此黑客,我怎样才能使这项工作正常进行?

1 个答案:

答案 0 :(得分:0)

感谢@Jerry Dodge,这与他与TTreeView.Data财产的问题相同。

我创建了一个简单的包装类,将a_list封装为IMyList,并将其保存在Objects[]中。

TListBox.OnClick处理程序中,它来自Objects[]就好了,我可以毫无问题地访问包装的值。它没有被这种方式破坏。

在包装器的析构函数中,我只是将NIL分配给a_list值,我没有其他问题。