程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> Delphi接口編程的兩大陷阱(3)

Delphi接口編程的兩大陷阱(3)

編輯:Delphi

有人說多此一舉嗎,接口引用只是個地址,沒必要手動設為nil。

OBJ2 := TC2.Create;
try
Intf1 := OBJ2;
Intf1.DO;
Finally
OBJ2.Free;
End;

結果可能還會出你的意料,還是非法地址訪問錯誤。為什麼?因為Delphi編譯器耍了個小聰明,它認為你忘記把這個地址引用置為nil了,所以你會自動給你加上,看來Delphi編譯器聰明過頭了J。

怎麼解決呢?

方法1,先把接口引用置為nil,再釋放對象。

Intf1 := nil;
OBJ2.Free;

方法2,把接口引用強制轉成指針類型再置為nil。

Pointer(Intf1) := nil;

此時相當於直接把地址清零,不會調用_IntfClear。

我傾向於使用第二種方法,這樣你就不用考慮先釋放誰的問題了。而且有些設計模式中你可能只持有接口引用,而且你也不知道引用的對象什麼時候釋放,此時就必須使用方法2。

例如考慮Composite模式。

TComposite = class(TComponent, I1)
Private
interList: TXContainer;//一個容器類,存放“葉子”的接口引用。
Public
Procedure Add (AIntf: I1);
function DO: Boolean;
End;

它應該釋放它的“葉子”嗎?顯然不是,那“葉子”是不是一定會晚於這個“合成對象”對象釋放呢?我想也不一定吧。如果強制這樣規定的話,就失去很多的靈活性。所以我們肯定想這些接口引用置nil時,不會和原對象發生什麼關系,以免對象被釋放後出非法地址訪問錯誤。考慮使用什麼容器呢?array?TList?TInterfaceList?

首先想到肯定是TInterfaceList了,因為我們是要容納的就是接口。但是對他進行Free時,它會把它所有容納的接口置為nil,這正是我們不想要的。或者我們可以在Free之前先把它存儲的接口引用轉為指針再置為nil。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved