self,指的是实例对象的指针吗?他是什么类型的变量,存储在什么位置!
例如TForm1类,在TForm1类的OnClose事件中有以下语句procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  //Action:=cafree;
  self.Free;
  self:=nil;
end;创建该类型的两个实例frm1和frm2,关闭frm1后,是否frm1的内存已经释放?(应该是释放了),
self:=nil  该如何理解?这句代码有什么作用吗?执行这句代码后,为何frm1跟frm2都<>nil,那么到底是谁=nil了?还是这句代码本身就有问题?

解决方案 »

  1.   

    你那个self就是form1实例,就是c++里的this
      

  2.   

    self为FORM1,SELF从英文字面上就可以理解,本身.
    self.free;为释放对象
    self:=nil;为将对象地址值空。“free;是把你的房子拆了,:=nil是把记录你住址的记录清空”,不怎么会表达这个。type test= class
        private
          a:string;
          procedure tt();
    end;
    implementation{$R *.dfm}
    procedure test.tt();
    begin
     Self.a := 'xxx';
    end;应该说是当前类的类型
      

  3.   

    “free;是把你的房子拆了,:=nil是把记录你住址的记录清空”
    有意思
      

  4.   

    “free;是把你的房子拆了,:=nil是把记录你住址的记录清空”free是把你的房子拆了,:=nil是把你这块地也收回去了
      

  5.   

    经过测试和讨论后,我自己来做个回答,不对的地方请指正
    --------------------------------------------------
    1.self,指的是实例对象的指针吗?      
    是的2.他是什么类型的变量,存储在什么位置!
    他是指向类实例的指针(那个对象调用它,他就指向那个对象),具体存储在内存的什么位置,我还不太清楚,应该是在动态存储区域。3.创建该类型的两个实例frm1和frm2,关闭frm1后,是否frm1的内存已经释放?
    已经释放了,因为执行了self.free;语句,但是frm1指针的指向位置并没有变。4.self:=nil 该如何理解?这句代码有什么作用吗?
    self可以赋值为nil,但是只要程序走出赋值语句的函数,self就又<>nil了(也可能没走出时self:=nil就无效了)。这句代码没有意义。5.执行这句代码后,为何frm1跟frm2都<>nil,这句话没有意义。
    这句话执行不执行,不会影响到frm1跟frm2变量中的指针的值,因为self跟frm1或虽然指向同一实例,但他们二者并不是一个指针, 所以执行这句代码后,frm1跟frm2都<>nil,而只是self=nil了?6.那么到底是谁=nil了?
    self:=nil ,只是nil了自己,但是随后self又不等于nil了。7.还是这句代码本身就有问题?
    这句代码没有意义,所以不能通过self:=nil 来影响frm1和frm2。补充:
    虽然self:=nil没有意义,但是self.free是有意义的,这句代码把self指向的实例的内存给释放了。也就是case5166所说的,住址还在通讯录中写着,但房子被强拆了!这时如果frm1根据通讯录中的地址去找房子是找不到的。
      

  6.   

    “:=nil是把你这块地也收回去了”,不是这样的吧?free后已经把地收回去了吧,否则free光强拆不收地,有那么傻吗?
      

  7.   

    self:=nil 也是有一定意义的。例如//随便点击btn1或btn2都不会报错
    procedure TForm1.btn1Click(Sender: TObject);
    begin
      self.Caption:='1';
      self:=nil;
    end;procedure TForm1.btn2Click(Sender: TObject);
    begin
      self.Caption:='2';
      self:=nil;
    end;这样依然不会报错//随便点击btn1或btn2都不会报错
    procedure TForm1.btn1Click(Sender: TObject);
    begin
      self:=nil;
      self.Caption:='1';  //虽然这句代码没起作用,但是程序没有报错
    end;procedure TForm1.btn2Click(Sender: TObject);
    begin
      self:=nil;
      self.Caption:='2';  //虽然这句代码没起作用,但是程序没有报错
    end;但是,这样写就报错了procedure TForm1.btn1Click(Sender: TObject);
    begin
      self:=nil;
      self.show;  //报非法访问地址错误,所以说self:=nil还是有一定意义的
    end;
      

  8.   


    seleron
    (旺旺贝贝) 
    我是来接分的,当然也随便说几句的
    self在过程中一般只是指“窗体”的名称的
      

  9.   

    self.Free ;// self 就是form1 ,把它的内存释放掉
    self := nil ; //ba form1这个对象的引用 置空 ,类似c中的防止野指针把
      

  10.   

    self.Free结果不一定是nil拆屋与收地是2个动作
      

  11.   

    如果只执行self.Free 而不nil,那么内存有没有被回收呢?
      

  12.   

    只执行frm1.Free ,我认为是内存已经被收回去了,虽然此时frm还<>nil,但是手中只有一张地契了,其实地盘上早就被某个开发商盖上商品房了。
      

  13.   

    self.Free就已经把对象释放了
    此时再引用SELF是错误的
    self := nil 意义不大。
      

  14.   

    拆屋(free)与收地(回收内存)应该是一个动作吧?nil只是没收地契。
      

  15.   

    不能这么说,按常理地契在你手中,那这块地就是你的,而NIL就像朋友间记录联系方式一样,朋友的联系方式改了,这个联系方式是无效的。而你删不删除这个联系方式异意思不大。
      

  16.   

    delphi的内存管理是比较有趣的,free之后,这块内存实际上是没有释放的,只有nil之后,内存才会释放。一般如果不需要的话,直接freeAndNil(对象);
      

  17.   

    “按常理地契(对象指针)在你手中,那这块地就是你的”,但是如果object.free后,这个地契已经无效了,你拿着它也去不回自己的地了。
    form1.free; 虽然此时form1<>nil,但是如果你去访问form1,就会出错。
      

  18.   

    这个跟我以前的理解不一致。
    我一直认为free之后就释放了内存了,nil只是使得指针置空,即使不nil,他所指向的内存已经无效了。
    到底是free之后释放内存还是nil之后释放内存?
      

  19.   

    procedure FreeAndNil(var Obj);
    var
      Temp: TObject;
    begin
      Temp := TObject(Obj);
      Pointer(Obj) := nil;
      Temp.Free;
    end;
      

  20.   

    我理解为类 本身
    看这个引用self在哪个类里边 就是指哪个类
      

  21.   

    其实,如果楼主了解了Delphi调用类方法的机制后,这个问题很容易理解的。
    如下这样的类定义type
      TMyTest = class
      public
        procedure Test(AValue: Integer);
      end;
      mt: TMyTest;Delphi在调用TMyTest的Test方法时,例如mt.Test(1),Delphi编译时,会把这个调用转成
    Test(mt, 1)的形式,而Self其实就是对mt的引用,实际上Self在这里只不过是Test方法的一个形参而已,所以,通过Self是可以调用Free方法的,但将Self设为nil,只不过是将一个形参设为nil了,没有什么意义。
    而楼主在7楼做的测试,实际上可以转换为SetCaption(nil, '1')这样的形式,虽然程序没有出现明显的异常,但实际上已经出错了,这段程序会将内存起始地址后面的某个位置的值设为'1',只是因为这个地址刚好能够访问,因此,没有报异常而已。
      

  22.   

    是这样的,但是self:=nil不能代替obj:=nil;
      

  23.   

    procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
      //Action:=cafree;
      self.Free;
      self:=nil;
    end;我这边delphi7的环境,self:=nil直接被优化没了
      

  24.   

    1.self,指的是实例对象的指针吗?   
     在一般方法中指的是实例本身,在类方法中指的是类本身2.他是什么类型的变量,存储在什么位置!
      指针变量, 存储在栈中EBP - $4,方法被调用时被当做局部变量第一个压栈, 调用时取EAX,因为寄存器更快,形如;
      procedure T***.AAA;
      var
        ......
        _Self: Pointer;<-- EBP - $4
      begin  
      end;
    以下可参看2
      

  25.   

    seleron 
    (旺旺贝贝) 
    你的分呀,真是难接呀
      

  26.   

    1. 在类方法中指的是类本身
    这句话不严谨,类方法中的self可能也代表子类,要看这个类方法在哪儿调用的。
    type
      ta = class
        class procedure c;
      end;
      tb = class(ta)
         procedure d;
      end;class procedure ta.c;
    begin
      showmessage(Self.ClassName);
    end;procedure tb.d;
    begin
      c
    end;procedure TForm1.FormCreate(Sender: TObject);
    var
      o: tb;
    begin
      O := tb.create;
      o.d;//显示tb,而不是ta
      o.Free
    end;2。方法被调用时被当做局部变量第一个压栈
    不对,默认是register调用方式,方法被调用时,self被当作第一个参数保存在eax中!并没有压栈!!!
      

  27.   

    self 是指运行时生成的那个对象
      

  28.   

    其实没有必要 self := nil
    指针 nil 是因为指针指向的内存块已经发生了改变,指过去的时候都不知道指的是什么.
    这里  self.free 以后.  再也看不到 self 这个指针了.
      

  29.   


    self.free以后,他的指针还是存在的。
    self代表某个被实例化的类对象,free后,这个对象所占用的内存被回收了,但是此时这个对象的指针并不等于nil,也就是说free后,其指针并没有被置空。