Free & FreeAndNil的使用。(100分)

  • 主题发起人 主题发起人 javesun
  • 开始时间 开始时间
那对象为置为nil时,发生了什么?
 
>>发生了什么
我还以为你已经明白了呢...

对象为置为nil——对象变量(实际上就是指向对象实例区域的指针)被清零了——仅此
而已。
你先把“对象变量”和“对象实例空间”区分清楚——前者是可擦写地址簿上的栏位,而
后者是巨大的“内存仓库”中实际堆放对象实例信息的区域。对象变量只是一个用来定位实
例数据的指针。如果你在释放这个实例之前就把指针“弄丢”了——那就别再想访问或者释
放这块对象实例信息区了。
 
creation-zy, 佩服。 大家风范
 
不好意思,我是明白了一点,在看了源代码后,明白了你所说的临时变量。
我也知道指针(我认为对象变量是一指针)在置为nil时,它指向了$00000000这个地方,我的意思是,在这之前,对象变量可能和其它很多的变量都有着关系,仅仅指向$00000000就可以把这些关系很安全的处理了吗?
 
将鼠标指针移到 FreeAndNil上面按住Ctrl键点击鼠标左键
 
>>很安全的处理了吗?
当然没有。
老大,你要深入的了解一下变量的基本概念。如果都能摆平,还要Free、FreeAndNil干什
么?对象间的引用关系可能很复杂,如果设计不合理,就算FreeAndNil也不能解决问题呢。


Obj:=TXXX.Create
//@@1,创建Obj对象
OtherObj.RefObj:=Obj
//对象实例指针Obj的值被赋给了OtherObj.RefObj
Obj:=nil
//此时,虽然Obj已被清零,但还没有完全“丢失”——因为OtherObj.RefObj已
//经保存了对它的引用。
Obj:=TXXX.Create
//@@2,创建一个新的Obj对象
FreeAndNil(OtherObj.RefObj)
//释放了@@1处所创建的对象
Obj.Free
//释放@@2处所创建的对象
 
to creation-zy:
很感谢你的解答,但最后的那个问题,是对象变量= nil,而不是FreeAndNil的问题了。老大能帮我解答一下吗?
--------------------------------引用上面的--------------------------
我也知道指针(我认为对象变量是一指针)在置为nil时,它指向了$00000000这个地方,我的意思是,在这之前,对象变量可能和其它很多的变量都有着关系,仅仅指向$00000000就可以把这些关系很安全的处理了吗?
 
我认为在上面所举的例子就是最典型的关系——这个对象同时还被别的对象指针所引用,
而这种情况的操作原理在上面也说明了。(如果我们将Obj:=nil改为Obj.Free,那么后面的
FreeAndNil(OtherObj.RefObj)就必定报错了)
上面是别人引用它的情况,还有一种就是它引用别的对象——如果你因为置nil而丢失了
Obj,那么它所引用的对象也就同时丢失了——有可能造成内存空间以及一些其它资源的无
法回收,其它没什么问题。(例如:一个Building对象内部包含有若干个Room对象,如果你
将Building丢失了,那么其内部的Room也就因为找不到而随之丢失了。而Free则能够保证正
确的释放相关的对象及资源。)
 
谢谢creation-zy,虽然还不是很明白。但你的心态让偶很是佩服。。。
偶回去会好好想想,再有什么不明白的,到时还要再麻烦你。。
 
Free的源码:
procedure TObject.Free;
begin
if Self <> nil then //当 对象 <> nil 的时候就调用Destroy释放对象
Destroy;
end;

FreeAndNil的源码:
procedure FreeAndNil(var Obj);
var
Temp: TObject;
begin
Temp := TObject(Obj)
//用一个临时对象保存 对象的值Obj(其实是保存地址)
Pointer(Obj) := nil
//然后将 对象 赋值为 nil (即对象变量已经指向 nil)
Temp.Free
//然后释放对象
end;

如果要每一条语句都弄清楚的话得理解 对象指针, 平时我们使用的对象名如Form1 这些都是指针, 指针是一个变量, 他的值是内存中的地址, 平时说的指针指向某个地方就是指针的值是那个 地址 自己可以测试一下, 新建一个工程,
ShowMessage(IntToStr(Integer(Form1)))

这样就显示出 Form1这个对象在内存中的位置
 
后退
顶部