首页 文章

Delphi接口和类变量类型

提问于
浏览
3

我已经读过,接口对于解码代码是一件好事,Nick Hodges已经写了很好的章节 . 读我已经生成了这段代码:

//interfaces
type
 ILocalization = interface
  ['{1D144BCE-7D79-4672-8FB5-235422F712EE}']
  function localize(const aWordId: string): string;
 end;

type
 IActions = interface
  ['{31E8B24F-0B17-41BC-A9E4-F93A8E7F6ECF}']
  procedure addWord(const aIndex, aWord: string);
  procedure removeWord(const aIndex: string);
 end;

//implementation
type
 TLocalization = class sealed (TInterfacedObject, ILocalization, IActions)
  private
   FTranslationList: TDictionary<string, string>;
  public
   constructor Create;
   destructor Destroy; override;
   //interface implementations
   function localize(const aWordId: string): string;
   procedure addWord(const aIndex, aWord: string);
   procedure removeWord(const aIndex: string);
 end;

我打算用这个类本地化(翻译)我的delphi android应用程序 .


当我要创建一个类的实例时,我会执行以下操作 .

var
 Italiano: TLocalization;
begin
 Italiano := TLocalization.Create;
end;

由于 TLocalization 应该继承AddRef,而Release I最终不会尝试这个,但即使Italiano是类类型而不是接口类型,这是否会发生?

我的意思是:

  • Italiano:TLocalization - >这里我可以使用所有方法

  • Italiano:ILocalization - >这里我只能使用localize函数

鉴于(正如我已经说过的)TLocalization继承了AddRef和Release我不需要释放,如果我已经正确理解的话 . 它应该与ILocalization相同,但它有其他好处吗?我不明白上述两种情况有什么不同

1 回答

  • 5
    var
      Italiano: TLocalization;
    begin
      Italiano := TLocalization.Create;
      // do stuff
    end;
    

    这可以让您了解混合不同生命周期模型的陷阱 . 如代码所示, AddRef 尚未被调用,因此引用计数为0.因此,您将泄漏此对象 .

    因此,您可以将代码更改为:

    var
      Italiano: TLocalization;
    begin
      Italiano := TLocalization.Create;
      try
        // do stuff
      finally
        Italiano.Free;
      end;
    end;
    

    现在你不泄漏 .

    大 . 但是,如果您参考了会发生什么?

    var
      Italiano: TLocalization;
      Localization: ILocalization;
    begin
      Italiano := TLocalization.Create;
      try
        Localization := Italiano as ILocalization;
        // do stuff
      finally
        Italiano.Free;
      end;
    end;
    

    现在 AddRef 在分配给 Localization 时被调用 . 因此引用计数变为1.当 Localization 超出范围时,将调用 Release 并且引用计数返回0并且实例将被销毁 . 不幸的是,你也在明确地摧毁它 . 物体需要被摧毁一次 .

    要遵循的最简洁和最简单的规则是不要混合使用寿命模型 . 如果您通过引用计数进行终身管理,请仅执行此操作 . 确保在创建对象时始终引用对象,并让编译器生成引用计数代码以管理生命周期 .

    确保遵循该规则的一种方法是确保您只通过接口引用访问该对象 . 像这样:

    var
      Italiano: ILocalization;
    begin
      Italiano := TLocalization.Create;
      // do stuff
    end;
    

相关问题