Essentially you are doing this correctly. Your casts are reasonable, and you understand the need to perform manual reference counting since you are holding the reference in a field of type Pointer
which does not perform reference counting.
P := ISuperObject(Node.Data);
If P
is assigned the value nil
that means that Node.Data
is equal to nil
. There's nothing more to say. Presumably there is some rather mundane reason for Data
being nil
, but it's nothing to do with the way you are casting.
Looking at your code, I would criticise it for mixing all the different concerns up together. You will find this task much easier if you can maintain a degree of isolation between the various different aspects.
One way to make life much simpler is to avoid using the untyped pointer Data
. Instead use a custom node type that can perform proper reference counting:
type
TMyTreeNode = class(TTreeNode)
private
FIntf: IInterface;
property
Intf: IInterface read FIntf write FIntf;
end;
You'll need to handle the OnCreateNodeClass
event of the tree view to get the control to create your node class.
procedure TForm1.TreeView1CreateNodeClass(Sender: TCustomTreeView;
var NodeClass: TTreeNodeClass);
begin
NodeClass := TMyTreeNode;
end;
Now whenever the tree view control creates a node instance it creates one of type TMyTreeNode
. Which happens to have a field to contain your interface. I've typed it as IInterface
here, but you'd use the more specific interface that fits your needs. And of course you can add whatever capability you please to your custom node type.
The mild bind to this is that you need to cast node references from TTreeNode
(as returned by the underlying tree view control) to TMyTreeNode
in order to gain access to the interface property. However, this bind is well worth it in my view because you can rely on the compiler to managed lifetime correctly, and so forget all about that aspect of the code. This will allow you to concentrate on your program rather than tedious boilerplate. Continuing down the path you are currently on looks like a recipe for memory leaks and access violations. Get the compiler to manage things and you can be sure to avoid any such pitfalls.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…