This question already has answers here:
How can free Interface implemented class?

(2个答案)


6年前关闭。





我之前打开过类似的主题,但是在尝试释放类实例时,我没有明确的错误原因“错误的指针操作”。现在我已经知道了原因,因此我打开一个新主题来揭示问题。

因此,导致此错误的原因是在实例化类ChatClient并将类本身的实例(TChatManager)作为参数传递时。该问题可能与对接口的TChatManager类的实现有关。

接口:

Type
  // An interface definition
  IMessageEvents = Interface(IInterface)
    ['{BD27EFC6-CC9A-437A-A8B8-16F722518836}']

    Procedure messageReceived(messageData: String);
  End;


TChatManager类:

Type
  TChatManager = Class(TInterfacedObject, IMessageEvents)
  Private
    cChatClient: TChatClient;
  Protected
    Procedure messageReceived(messageData: String); Overload;
  Public
    Constructor Create; Overload;
    Destructor Destroy; Override;
  End;

Implementation

Constructor TChatManager.Create;
Begin
  Inherited Create;
  self.cChatClient := TChatClient.Create(self); // self class instance as parameter
End;

Procedure TChatManager.messageReceived(messageData: String);
Begin

End;

Destructor TChatManager.Destroy;
Begin
  Inherited Destroy;
End;


TChatClient类:

Type
  TChatClient = Class(TObject)
  Private
    iMsgEvents: IMessageEvents;
  Protected
  Public
    Constructor Create(iMsgEvents: IMessageEvents); Overload;
    Destructor Destroy; Override;
  End;

Implementation

Constructor TChatClient.Create(iMsgEvents: IMessageEvents);
Begin
  Inherited Create;
  self.iMsgEvents := iMsgEvents;
End;

Destructor TChatClient.Destroy;
Begin
  Inherited Destroy;
End;


主要:

cChatManager: TChatManager;
self.cChatManager := TChatManager.Create;
self.cChatManager.Free; // Failed


任何人都可以解释我实施的不好吗?谢谢。

注意:类不完整,我删除了释放对象等的一些方法。

问候。

最佳答案

问题的答案是使用以下TInterfacedObject方法:

procedure TInterfacedObject.BeforeDestruction;
begin
  if RefCount <> 0 then
    Error(reInvalidPtr);
end;


您的代码正在销毁具有非零TChatManager字段的RefCount实例,因为它由TChatClient实例引用。



OP代码无法固定,应该重新设计,因为在当前形式下,TChatManager实例应在TChatClient析构函数中销毁(通过设置iMsgEvents:= nil),这很奇怪! :)

10-08 12:20