为什么要这样写?
procedure FreeAndNil(var Obj);
var
Temp: TObject;
begin
Temp := TObject(Obj);
Pointer(Obj) := nil;
Temp.Free;
end;这样不行吗? 我经常这样用啊.
procedure FreeAndNil(var Obj: TObject);
begin
Obj.Free;
Obj := nil;
end;
procedure FreeAndNil(var Obj);
var
Temp: TObject;
begin
Temp := TObject(Obj);
Pointer(Obj) := nil;
Temp.Free;
end;这样不行吗? 我经常这样用啊.
procedure FreeAndNil(var Obj: TObject);
begin
Obj.Free;
Obj := nil;
end;
//这是Indy9 IdGlobal.pas中的写法procedure FreeAndNil(var Obj);
var
P: TObject;
begin
if TObject(Obj) <> nil then begin
P := TObject(Obj);
TObject(Obj) := nil; // clear the reference before destroying the object
P.Free;
end;
end;
后者调用:FreeAndNil(TObject(Obj));
前者调用:FreeAndNil(Obj);
后者更简洁吧
var
P: TObject;
begin
if TObject(Obj) <> nil then begin
P := TObject(Obj);
TObject(Obj) := nil; // clear the reference before destroying the object
P.Free;
end;
end;indy真是多此一举,Free本身就会判断对象指针是否nil;我之所以有这一问是因为Delphi所有的对象都是基于Tobject的,完全没必要用一个
无类型变量作参数啊.
估计他之所以设个中间变量,是以防万一,怕在Free的过程中其他代码又调用该对象,
这样一来就线程安全了?
不解.
>>这样一来就线程安全了? 把原来的Obj设为nil,对多线程来说,启不是更加不好?
因为指针不见得都是TObject.
因为指针不见得都是TObject.那第二个方法不更好?
传进来的是一个没有类型的,要先转为 TObject; Temp := TObject(Obj);
Pointer(Obj) := nil; //这样也可以减少对Obj的引用
Temp.Free;
为什么要不让它减少对Obj的引用呢?
var
Temp: TObject;
begin
Temp := TObject(Obj);
Pointer(Obj) := nil; //在释放对象前清除对其的引用
Temp.Free;
end;
对C语言的指针清楚的话,这个应该不难理解。
对于局部变量,大部分情况只要free就可以,局部变量在函数运行结束会被自动释放的,和普通的变量没有区别。但是如果你没有free,那么只有指针变量本身被释放,指针指向的地址则成了内存泄漏。
谁不知道“free是释放指针指向的内存,nil是把指针变量本身的值”,
问题是Borland写 FreeAndNil 这个函数时为什么要那样写?
而不是通常的 xxx.Free; xxx:=nil; 这种写法。
帮助中说:“Obj must be an instance of a TObject descendent class”,我想这个写法只是确保可以得到一个干净的“返回值”,甚至在obj.free出错时,
它相当于
try
obj.free
finally
obj=nil;
end;
var
Temp: TObject;
begin
Temp := TObject(Obj);
Pointer(Obj) := nil;
Temp.Free;
end;
其实意思和
procedure FreeAndNil2(var Obj: TObject);
begin
Obj.Free;
Obj := nil;
end;
是一样的为什么要这样写?主要是为了避开类型检查传递任意类型的对象给FreeAndNil1都能通过编译
但是FreeAndNil2只能传递TObject,其它类型都不可以