//介面申明
type
ITestObj = interface
['{275C452D-5A6B-49B5-9527-C5D1F582A378}']
function Gettestid: Integer; stdcall;
function Gettestname: string; stdcall;
procedure Settestid(const Value: Integer); stdcall;
procedure Settestname(const Value: string); stdcall;
function testhello: string; stdcall;
property testid: Integer read Gettestid write Settestid;
property testname: string read Gettestname write Settestname;
end;
ITestObjs = interface
['{3E517EF1-944D-43F3-AC69-390396977B71}']
function ByID(nID: Integer): ITestObj; stdcall;
procedure Reset;
end;
IApps = interface
['{9C4994E3-B41A-47C6-AD8E-8A2AA23EC3E8}']
function TestObjs: ITestObjs; stdcall;
end;
var
TestInter: IApps;
//介面實作
uses
utestInterface, Classes, SysUtils;
type
TTestObj = class(TInterfacedObject, ITestObj)
private
FID: Integer;
FName: string;
function Gettestid: Integer; stdcall;
function Gettestname: string; stdcall;
procedure Settestid(const Value: Integer); stdcall;
procedure Settestname(const Value: string); stdcall;
public
constructor Create;
destructor Destroy; override;
function testhello: string; stdcall;
end;
TTestObjs = class(TInterfacedObject, ITestObjs)
private
List: TList;
public
constructor Create;
destructor Destroy; override;
function ByID(nID: Integer): ITestObj; stdcall;
procedure Clear;
procedure Reset;
end;
TApps = class(TInterfacedObject, IApps)
private
_ITestObjs: ITestObjs;
public
function TestObjs: ITestObjs; stdcall;
end;
//具體實作方法
function TTestObjs.ByID(nID: Integer): ITestObj;
var
I: Integer;
TestObj: TTestObj;
begin
Result := nil;
if not Assigned(List) then
Exit;
for I := 0 to List.Count - 1 do
begin
TestObj := TTestObj(List[I]);
if Assigned(TestObj) and (TestObj.Gettestid = nID) then
begin
Result := TestObj;
Break;
end;
end;
// TODO -Eternally: TTestObjs.ByID default body inserted
end;
procedure TTestObjs.Reset;
var
I: Integer;
TestObj: TTestObj;
begin
if not Assigned(List) then
List := TList.Create;
Clear;
for I := 1 to 5 do
begin
TestObj := TTestObj.Create;
TestObj.Settestid(I);
TestObj.Settestname('TestObj' + IntToStr(I));
List.Add(TestObj);
end;
// TODO -Eternally: TTestObjs.Reset default body inserted
end;
//------------------------------------------------------------------------------
// 總介面入口
//------------------------------------------------------------------------------
function _WZInterface: IApps;
var
_TestObjs: TTestObjs;
implementation
var
_testClasses: TApps;
//呼叫
procedure TForm1.Button1Click(Sender: TObject);
var
nID: Integer;
Str: string;
begin
nID := 2;
Str := TestInter.TestObjs.ByID(nID).testname;
ShowMessage(Str);
//呼叫完這個按鈕事件后 ByID出來的介面會被呼叫TTestObj的Destroy釋放,為何會呼叫Destroy釋放?沒有手動釋放的情況下
// TODO -Eternally: TForm1.Button1Click default body inserted
end;
/呼叫完這個按鈕事件后 ByID出來的介面會被呼叫TTestObj的Destroy釋放,為何會呼叫Destroy釋放?沒有手動釋放的情況下
uj5u.com熱心網友回復:
這是典型的介面模式和物件模式混用造成的坑,恭喜入坑~在List保留的是物件參考,這時介面的參考計數機制并不起作用。
當在ByID呼叫時,介面參考機制開始時+1, 事件處理結束后-1, 結果為0
所以,對應的物件就銷毀了。
正確的做法是: 應該在List中保留介面參考,也就是物件Create出來后
馬上只使用它的介面型別的變數進行處理。。。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/64636.html
標籤:VCL組件開發及應用
上一篇:Delphi下載版本求解!!!
