【发布时间】:2013-08-11 11:25:35
【问题描述】:
如果我理解正确,这很好:
type
IMyInterface = interface['{60E314E4-9FA9-4E29-A09A-01B91F2F27C7}']
procedure MyMethod;
end;
type
TMyIClass = class(TInterfacedObject, IMyInterface)
public
procedure MyMethod; // Forget the implementations in this example
end;
var
lMyIClass: IMyInterface;
lSupports: Boolean;
begin
lMyIClass := TMyIClass.Create;
lSupports := Supports(lMyIClass,IMyInterface);
Memo1.Lines.Add('lMyIClass supports IMyInterface: ' + BoolToStr(lSupports,true));
if lSupports then DoSomethingWith(lMyIClass);
现在我有一个实现多个接口的类:
type
IFirstInterface = interface['{4646BD44-FDBC-4E26-A497-D9E48F7EFCF9}']
procedure SomeMethod1;
end;
ISecondInterface = interface['{B4473616-CF1F-4E88-9EAE-1AAF1B01A331}']
procedure SomeMethod2;
end;
TMyClass = class(TInterfacedObject, IFirstInterface, ISecondInterface)
procedure SomeMethod1;
procedure SomeMethod2;
end;
我可以调用另一个重载的 Support() 返回接口并用它做一些事情):
var
MyClass1,MyClass2 : TMyClass;
i1: IFirstInterface;
i2: ISecondInterface;
bSupports: Boolean;
begin
Memo1.Clear;
MyClass1 := TMyClass.Create;
bSupports := Supports(MyClass1,IFirstInterface,i1);
if bSupports then
begin
Memo1.Lines.Add('MyClass1 supports IFirstInterface');
DoSomethingWith(i1);
end
else
Memo1.Lines.Add('MyClass1 does not support IFirstInterface');
bSupports := Supports(MyClass1,ISecondInterface,i2);
if bSupports then
begin
Memo1.Lines.Add('MyClass1 supports ISecondInterface');
DoSomethingElseWith(i2);
end
else
Memo1.Lines.Add('MyClass1 does not support ISecondInterface');
MyClass1 := nil;
i1 := nil;
i2 := nil;
MyClass2 := TMyClass.Create;
bSupports := Supports(MyClass2,IFirstInterface,i1);
if bSupports then
begin
Memo1.Lines.Add('MyClass2 supports IFirstInterface');
DoSomethingWith(i1);
end
else
Memo1.Lines.Add('MyClass2 does not support IFirstInterface');
bSupports := Supports(MyClass2,ISecondInterface,i2);
if bSupports then
begin
Memo1.Lines.Add('MyClass2 supports ISecondInterface');
DoSomethingElseWith(i2);
end
else
Memo1.Lines.Add('MyClass2 does not support ISecondInterface');
我对此有三个问题:
MyClass1, MyClass2现在是对象类型,而不是简单示例中的接口类型。这样可以吗?我应该 Free() 还是 'nil' MyClass1 或者甚至不理会它?
在处理完 2. 之后,关于引用计数是否仍需要两条
ix:= nil语句?
【问题讨论】:
-
(1) 是的,(2) 你创建了它并且没有使用 addRef;等等,是的
Free它,(3)是的,您将它们用作接口对象。现在,如果您将 lMyClass1 分配给一个接口,那么 不要 释放它;你只是把它放到引用地里 -
你所做的一切都很好......你必须注意什么。 DoSomethingWith(MyClass2 as IFirstInterface);您将混合模型...“As” Ref 将您的 MyClass2 计数加 1,然后当 DoSomethingWith 完成时,它 Ref 计数回减 0...如果 ref count = 0,则 free 是您的对象。跨度>
-
应该读作“完成它Ref倒计时1”
-
您应该知道的事情...如果您知道您的对象支持该接口,则不必使用 Support。你可以只写 i1 := MyClass2。编译器将确保您的对象支持该接口。
-
您正在混合类引用和接口引用。这是一个很大的禁忌。您不需要以这种方式使用 Supports。只需将所有变量声明为接口,编译器就会告诉您是否正确布局。不要让自己难过。
标签: delphi interface reference-counting