我已经读过,接口对于解码代码是一件好事,而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是类类型而不是接口类型,这是否会发生?
我的意思是:
鉴于(正如我已经说过的)TLocalization继承了AddRef和Release I,如果我理解正确,则不必释放。它应该与ILocalization相同,但它有其他好处吗?我不明白上面两种情况的区别是什么
答案 0 :(得分: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;