TInterfaceList에 Interface를 하나 추가하면 그 해당 Inteface item의 RefCount는 어떻게 될까?
굉장히 궁금했던 사항인데 오늘 그 결과를 속시원히 파헤쳐 보았다.
1. TInterfaceList에 Inteface를 하나 추가하면 해당 Interface Item의 RefCount가 늘어날까?
-> 증가한다. 1만큼 증가한다.
2. 그럼 TInterfaceList에서 item 하나를 빼면?
-> RefCount가 1만큼 감소한다. 감소만 하는거지 TInterfaceList에서 뺐다고 해서 자동으로 삭제되는 건 아니다. 그냥 1만큼 감소만 하는거다. 그런데 만약 여기서 빼서 RefCount = 0이 되면 그 때는 자동으로 삭제된다.
3. Interface를 하나 생성하면 생성할 당시의 RefCount는 얼마인가?
1이다. 생성되는 순간 1이 된다.
4. 인스턴스가 생성되었는지 여부를 알 수 있는 방법은 없는가?
있다. Interface가 하나 생성되면 procedure AfterConstruction; override; 이 함수가 호출되어 진다. 해제될 때는 procedure BeforeDestruction; override; 함수가 호출된다.
5. 만약 같은 TInterfaceList에 여러 번 Add 하면 RefCount는 어떻게 되는가?
추가한 만큼 RefCount가 올라간다. 만약 2번 Add했다면 RefCount는 2만큼 올라간다.
6. interface를 담고 있던 TInterfaceList를 free하면 그 안의 interface 객체는 어떻게 되는가?
추가한 수만큼 RefCount가 빠진다.
테스트한 전체 코드는 다음과 같다.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
IFoo = Interface
function GetA() : Integer;
end;
type
TFoo = Class(TInterfacedObject, IFoo)
function GetA() : Integer;
procedure BeforeDestruction; override;
procedure AfterConstruction; override;
end;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ TFoo }
procedure TFoo.AfterConstruction;
begin
inherited;
showMessage('인스턴스 생성 후');
end;
procedure TFoo.BeforeDestruction;
begin
inherited;
showMessage('삭제 되기 직전');
end;
function TFoo.GetA: Integer;
begin
result := 1;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
pIFoo : TFoo;
list : TInterfaceList;
nRef : Integer;
begin
list := TInterfaceList.Create;
try
// 생성시
pIFoo := TFoo.Create;
nRef := TInterfacedObject(pIFoo).refCount;
showMessage('생성하고 난 직후 : ' + intToStr(nRef));
// 일부러 하나 올리기
pIFoo._AddRef();
nRef := TInterfacedObject(pIFoo).refCount;
showMessage('일부러 하나 올린 후 : ' + intToStr(nRef));
// 일부러 하나 올리기
pIFoo._AddRef();
nRef := TInterfacedObject(pIFoo).refCount;
showMessage('일부러 하나 올린 후 : ' + intToStr(nRef));
// 일부러 하나 내리기
pIFoo._Release();
nRef := TInterfacedObject(pIFoo).refCount;
showMessage('일부러 하나 내린 후 : ' + intToStr(nRef));
// 리스트에 추가한 후
list.Add(pIFoo);
nRef := TInterfacedObject(pIFoo).refCount;
showMessage('리스트에 추가 후 ' + intToStr(nRef));
// 리스트에서 삭제한 후
list.Remove(pIFoo);
nRef := TInterfacedObject(pIFoo).refCount;
showMessage('리스트에서 삭제 후' + intToStr(nRef));
// pIFoo가 자동으로 삭제되면 Dangling Pointer가 된다.
// 그래서 Assigned() 함수로도 삭제가 된 인터페이스인지 여부를 확인할 수 없다.
// 그리고 이미 자동으로 삭제된 인터페이스는 RefCount가 이미 쓰레기값이기 때문에
// RefCount를 확인하는 것도 아무런 의미가 없다.
if (pIFoo = NIL) then
showMessage('pIFoo = NIL');
if (NOT assigned(pIFoo)) then
showMessage('pIFoo is NOT Assigned');
finally
list.Free;
end;
// TInterfaceList를 해제한 후.
nRef := TInterfacedObject(pIFoo).refCount;
showMessage('리스트를 해제한 후' + intToStr(nRef));
end;
end.
'프로그래밍 > 델파이' 카테고리의 다른 글
1을 001로 보이게 하려면? (0) | 2006.11.06 |
---|---|
팁 - 델파이 COM에 이벤트 발생시키기.zip (0) | 2006.11.06 |
델파이에서 ActiveX 콘트롤 만들기(ActiveForm 쓰지 않고) (0) | 2006.11.05 |
Delphi 7 ActiveForm 패치 (0) | 2006.11.05 |
DBGrid에서 메모필드 보이게 하기 (0) | 2006.10.18 |