类自释放合理么?解决办法
类自释放合理么?
也没有发现内存泄漏
在实际编程中,因为类要处理一些数据,在类处理完毕后会触发回调函数,在函数中我会把类的Self传递过去,并释放
不知道这样做是否安全,是不是一个不良的习惯?
------解决方案--------------------
把'ok'换成一个成员变量试试!test之后show就会出错!!!
而且FreeAndNil(Self)之后,o依然不为nil,你试试!
------解决方案--------------------
这样做,肯定是不对的, 显然你释放后再次调用o.show这个方法里没有再次访问实例里成员, 所以这里即使你不创建 tabc 一样可以这样做 o: Tabc; o.show; 但是一旦你的show里访问了私有类实例成员 那么必然会发生内存违规(也要看运气)
------解决方案--------------------
即使o:tabc ; o:=nil, o.show也不会出错, 问题在于show在这里根本不访问私有的成员变量, 所以o 本身实例是什么都无所谓 , 一旦你的show里有了访问私有变量的代码, 就肯定有问题了
------解决方案--------------------
一般的原则是由创建者释放。当然也有例外,比如创建成接口,比如单实例,比如由objectlist来管理等等。
------解决方案--------------------
类中释放自己,要分情况,当一个实例确定不再使用时,可以引一个方法来释放自己
如
Txxx = Class(Txxx)
public
procedure Free2;
end;
procedure Txxx.Free2;
begin
DoSomething;
Free;
end;
在Free2中,调用 Free;就象前面两位所说,Free后不能在引用任何非Class定义的类的数据成员,
这里需要注意一下,在类的事件中引用Free就要留意,有些事件调用返回后,还会访问类的数据成员,因此要出错,
比如想在 Form.OnActivate中,Free掉Self就要出错
当你调用
实例.方法的时候,就是把实例的地址传到方法中当Self使用
比如:
var
o: tabc;
begin
o := nil;
o.test;
你在Tabc.test中判断Self肯定=NIL
再举个例:
procedure TABC.AAA(i : integer);
//该过程实际上就是普通过程的这种格式: procedure (Self : TABC; i : integer);
begin
end;
当实行
ABC.AAA(1)
实际上是执行 AAA(ABC , 1);
tabc = class
procedure test;
procedure show;
end;
procedure tabc.show;
begin
ShowMessage('ok');
end;
procedure tabc.test;
begin
FreeAndNil(Self);
end;
var
o: tabc;
begin
o := tabc.Create;
o.test; //内部释放
o.show; //仍然可以弹出提示窗
end;
也没有发现内存泄漏
在实际编程中,因为类要处理一些数据,在类处理完毕后会触发回调函数,在函数中我会把类的Self传递过去,并释放
不知道这样做是否安全,是不是一个不良的习惯?
------解决方案--------------------
把'ok'换成一个成员变量试试!test之后show就会出错!!!
而且FreeAndNil(Self)之后,o依然不为nil,你试试!
------解决方案--------------------
这样做,肯定是不对的, 显然你释放后再次调用o.show这个方法里没有再次访问实例里成员, 所以这里即使你不创建 tabc 一样可以这样做 o: Tabc; o.show; 但是一旦你的show里访问了私有类实例成员 那么必然会发生内存违规(也要看运气)
------解决方案--------------------
即使o:tabc ; o:=nil, o.show也不会出错, 问题在于show在这里根本不访问私有的成员变量, 所以o 本身实例是什么都无所谓 , 一旦你的show里有了访问私有变量的代码, 就肯定有问题了
------解决方案--------------------
一般的原则是由创建者释放。当然也有例外,比如创建成接口,比如单实例,比如由objectlist来管理等等。
------解决方案--------------------
类中释放自己,要分情况,当一个实例确定不再使用时,可以引一个方法来释放自己
如
Txxx = Class(Txxx)
public
procedure Free2;
end;
procedure Txxx.Free2;
begin
DoSomething;
Free;
end;
在Free2中,调用 Free;就象前面两位所说,Free后不能在引用任何非Class定义的类的数据成员,
这里需要注意一下,在类的事件中引用Free就要留意,有些事件调用返回后,还会访问类的数据成员,因此要出错,
比如想在 Form.OnActivate中,Free掉Self就要出错
当你调用
实例.方法的时候,就是把实例的地址传到方法中当Self使用
比如:
var
o: tabc;
begin
o := nil;
o.test;
你在Tabc.test中判断Self肯定=NIL
再举个例:
procedure TABC.AAA(i : integer);
//该过程实际上就是普通过程的这种格式: procedure (Self : TABC; i : integer);
begin
end;
当实行
ABC.AAA(1)
实际上是执行 AAA(ABC , 1);