【问题标题】:How to keep interfaced objects from being deleted when added to an Items.Objects[] list?添加到 Items.Objects[] 列表时如何防止接口对象被删除?
【发布时间】:2014-09-04 17:59:53
【问题描述】:

我有一个这样定义的接口对象(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 会按预期显示。

这似乎是一个不必要的 hack,它可能是由于演员将项目添加到 Objects[] 中造成的,这是必需的,因为它的类型是 IMyList,它不是从 TObject 派生的,而TMyList 是。

我怎样才能在不诉诸这种 hack 的情况下使其正常工作?

【问题讨论】:

  • 我最近问了一个几乎相同的问题:stackoverflow.com/questions/25611118/… 但是我不确定我是否会认为它是重复的。
  • 是的,看起来是同一个问题。感谢您指出。我会尝试类似的解决方案。
  • 别忘了,如果你确实使用了“hack”a_list._AddRef,那么请确保使用 a_list._Release 减少它
  • 是的,我在 FormDestroy 中做到了。
  • 或者更好的是停止使用 gui 控件作为容器。完全不需要在Objects[] 中添加任何内容。维护一个适当的容器并从您的 gui 中显示该容器的视图。

标签: delphi


【解决方案1】:

感谢@Jerry Dodge,这与他在使用TTreeView.Data 属性时遇到的问题相同。

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

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

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

【讨论】:

    猜你喜欢
    • 2018-03-15
    • 2016-01-02
    • 1970-01-01
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 2019-06-02
    • 1970-01-01
    相关资源
    最近更新 更多