Delphi发布接口指针

时间:2017-09-23 13:47:14

标签: delphi interface treeview delphi-10.2-tokyo

我在使用Delphi中的接口时遇到了困难。这个问题可能微不足道,但我是Delphi的新手,所以请原谅。

我有一个带有自定义节点的TreeView,它拥有一个对象的接口(基本上就像在这里提出的那样:Storing interface pointer inside tree view nodes)。

问题是,一旦我删除了一个节点(为了重绘树视图)并将接口变量设置为nil(由于某种原因,我已经完全不了解接口,因此无法完全理解)最奇怪的事情发生了:

在我的对象中,包含列表,整数和字符串变量,字符串和列表将设置为空,而整数保持不变。

我无法解释这一点。有没有人知道解决方法或这种行为的可能原因?顺便说一句,我使用的是Delphi 10.2 Tokyo。

这是我非常不引人注目的破坏方法:

myNode.destroy;
begin
  intf:= nil;// intf holds the interface to the object
end;

编辑:这是我的代码的简化版本:

我指的对象:(我有几个类似的类看起来像obj,但略有不同,我不知道哪一个将存储在界面中,但都共享这些变量)

Obj = class(InterfacedObject, IMyinterface)
  count: integer;  //this remains the same
  children: array of ChildObj;  //this will be emptied
  name: string;  //this will be set to ''
  procedure addChild;
  procedure IMyInterface.add = addChild;
end;

我自定义的treeNode:

MyNode = class(TTreeNode)
  Intf: IMyinterface;
  destructor destroy; override;
end;

我的班级管理TreeView:

MyForm.ReloadTree;
begin
  if myTreeView.Items.Count > 0 then
  begin
    myTreeView.Items.Clear;
  end
  for I:= 0 to RootObj.Count-1 do
  begin
    myTreeView.Items.AddChild(MyTreeview.Items[0], RootObj.Children[i].name);
    (myTreeView.Items[0][i] as MyNode).Intf := Intf(RootObj.Children[i]);
    //I will proceed iterating over all children and their children, doing 
    //the same process, a level higher in the treeView
    //...
  end;
end;

1 个答案:

答案 0 :(得分:0)

  

在我的对象中,其中包含一个列表,一个整数和一个字符串变量,字符串和列表将设置为空,而整数保持不变。

这是完全正常的行为。字符串和接口是编译器管理的类型。整数不是。当一个对象被破坏时,编译器管理的数据成员会根据需要自动解除分配,在字符串和接口的情况下,涉及指向其引用数据的指针。包含对象本身并未完全归零,因此非托管类型(如整数)不会在内存中被覆盖。

现在,正如所说,我在ReloadTree()程序中看到了一些错误。

  1. 您的for循环超出了RootObj.Children[]列表的上限。

  2. 调用AddChild()时,第二个参数为string。您正在该参数中传递RootObj.Children[i]。但是,在下一个语句中,您在分配RootObj.Children[i]字段时向接口输入相同的MyNode.Intf值。 string不是接口。那么,RootObj.Children[]究竟包含什么 - 字符串或接口?

  3. 分配MyNode.Intf字段时,您始终访问TreeView中的第一个节点,而不是新添加的节点。