无法释放接口实现的类

时间:2013-12-22 16:32:16

标签: delphi class interface free

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

因此出现此错误的原因是在实例化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

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

注意:这些类不完整,我删除了一些发布对象等的方法......

问候。

1 个答案:

答案 0 :(得分:4)

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

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

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


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