Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 无法释放接口实现的类_Delphi_Class_Interface_Free - Fatal编程技术网

Delphi 无法释放接口实现的类

Delphi 无法释放接口实现的类,delphi,class,interface,free,Delphi,Class,Interface,Free,我以前打开过一个类似的主题,但在尝试释放类实例时,没有明确的原因导致错误“无效指针操作”。现在我已经知道了原因,所以我打开了一个新的话题,来揭露这个问题 因此,此错误的原因是在实例化类ChatClient并将类本身的实例(TChatManager)作为参数传递时。问题可能与类TChatManager到接口的实现有关 界面: Type // An interface definition IMessageEvents = Interface(IInterface) ['{BD27E

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

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

界面:

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

    Procedure messageReceived(messageData: String);
  End;
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;
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
班级管理者:

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

    Procedure messageReceived(messageData: String);
  End;
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;
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
类TChatClient:

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

    Procedure messageReceived(messageData: String);
  End;
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;
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
Main:

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

    Procedure messageReceived(messageData: String);
  End;
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;
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;
销毁前的程序TInterfacedObject; 开始 如果RefCount为0,则 错误(reInvalidPtr); 结束; 您的代码正在销毁具有非零
RefCount
字段的
TChatManager
实例,因为它被
TChatClient
实例引用



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

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

procedure TInterfacedObject.BeforeDestruction;
begin
  if RefCount <> 0 then
    Error(reInvalidPtr);
end;
销毁前的程序TInterfacedObject; 开始 如果RefCount为0,则 错误(reInvalidPtr); 结束; 您的代码正在销毁具有非零
RefCount
字段的
TChatManager
实例,因为它被
TChatClient
实例引用



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

@LU-RD感谢您的回复。类不完整,我删除了释放对象的方法。但是问题不在那里。@David,是的,我知道,事实上在第一行我已经说过我以前也发布过类似的问题。事实是,虽然问题已经解决了,但我不清楚到底是什么导致了错误,所以我不得不打开一个新的话题。我想我已经解释过了。也许还不够好。关键是接口引用控制生命周期。你必须停止持有接口引用以外的引用。@David是的,我知道,但我留下了一些疑问。我必须学习更多。谢谢。@LU RD感谢您的回复。类不完整,我删除了释放对象的方法。但是问题不在那里。@David,是的,我知道,事实上在第一行我已经说过我以前也发布过类似的问题。事实是,虽然问题已经解决了,但我不清楚到底是什么导致了错误,所以我不得不打开一个新的话题。我想我已经解释过了。也许还不够好。关键是接口引用控制生命周期。你必须停止持有接口引用以外的引用。@David是的,我知道,但我留下了一些疑问。我必须学习更多。谢谢你。这就是引起例外的原因。真正的问题是将
cChatManager
类型的变量
TChatManager
@user246408分配给
cChatManager
,导致引用计数的生存期管理被破坏。谢谢,现在我明白了出现此错误的原因。大卫也谢谢你的回答。@DavidHeffernan-这是个好问题;当然,混合对象和接口引用是一种糟糕的设计,但找到bug本身却是一件有趣的事情。这就是引发异常的原因。真正的问题是将
cChatManager
类型的变量
TChatManager
@user246408分配给
cChatManager
,导致引用计数的生存期管理被破坏。谢谢,现在我明白了出现此错误的原因。大卫也谢谢你的回答。@DavidHeffernan-这是个好问题;当然,混合使用对象和接口引用是糟糕的设计,但找到bug本身是一件有趣的事情。