问个弱的问题,关于TDataSet释放(100分)

  • 主题发起人 主题发起人 wanyingsong
  • 开始时间 开始时间
W

wanyingsong

Unregistered / Unconfirmed
GUEST, unregistred user!
我写了个函数返回DataSet,不知道返回的这个DataSet是不是一定要释放?<br>函数是<br>function ExecSql(Sql:string):TDataSet;<br>var qry:TAdoquery;<br>begin<br> &nbsp;qry:=Tadoquery.create(nil);//是用nil呢?还是self?还是application?有什么区别<br> &nbsp;qry.Connection:=adoconnection1;//这个conn已经设置好的<br> &nbsp;qry.sql.add(sql);<br> &nbsp;result:=qry.open;<br>end;<br><br>procedure UserDataset;<br>var ds:Tdataset;<br>begin<br> &nbsp;ds:=execsql('select * from sysobjects');<br> &nbsp;showmessage(inttostr(ds.recordcount));<br> &nbsp;ds.free; &nbsp;//要不要free,如果不free退出这个过程后它会不会自己free掉?<br>end;<br><br>procedure UseDataset2;<br>begin<br> &nbsp;showmessage(inttostr(execsql('select * from sysobjects').recordcount));<br> &nbsp;//那这个呢?dataset是不是释放掉了<br>end;
 
若不用了就要free掉.<br>前面用 qry:=Tadoquery.create(self);
 
Tadoquery.create(nil);<br>Tadoquery.create(self);<br>Tadoquery.create(application);<br>这三个都有什么区别?
 
Tadoquery.create(nil); &nbsp;//组件的所有者为空,要自已负责释放<br>Tadoquery.create(self); //组件的所有者为self,self会负责释放<br>Tadoquery.create(application);//组件的所有者为应用程序,应用程序会负责释放<br><br>一般来讲,自已动态创建的组件,在使用后都自已释放比较好些。
 
Tadoquery.create(nil);//一定要释放<br>Tadoquery.create(self);//理论上不用释放,随着拥有者的释放而释放<br>Tadoquery.create(application);//看情况,随着应用程序的释放而释放<br><br><br>写个过程;把创建的DataSet传进去做完事自己手动释放!<br>写函数:用完后判断是否存在,存在就手动释放!
 
用過程的方式,用完後自己Free 是最好的<br>我一直是這樣,問題要少些
 
三者属主不同。。。<br>构造的方法都是继承并覆盖自先祖类TComponent的构造方法,<br>constructor Create(AOwner:TComponent);virtual;<br>1、Tadoquery.create(self);中AOwner的参数是self,它指的是Form对象,那么每次创建一个Tadoquery组件,通过构造方法的AOwner参数,自动将目标组件对象添加到属主组件对象的内部组件对象列表上。创建这样的有属主的组件不需要手工销毁,当其属主self即Form销毁时自动销毁,否则可能销毁两次。创建组件时指定属主在效率上也是不上算的,每创建一个都要调用InsertComponent方法。<br>2、建议用使用Tadoquery.create(nil);不指定属主,这样可以避免调用InsertComponent方法,可明显提高效率,需手工释放。<br>3、Tadoquery.create(application);中Application也是组件对象,也是TComponent的派生类,这样调用不仅影响其所属组件对象,也影响到Form对象的所属组件对象。应避免。
 
谢谢各位富翁!那我的这个 <br>procedure UseDataset2;<br>begin<br> &nbsp;showmessage(inttostr(execsql('select * from sysobjects').recordcount));<br> &nbsp;//那这个呢?dataset是不是释放掉了<br>end;<br>那这个过程就不能这样调用了?
 
这个dataset就是<br>function ExecSql(Sql:string):TDataSet;<br>var qry:TAdoquery;<br>begin<br> &nbsp;qry:=Tadoquery.create(nil);//是用nil呢?还是self?还是application?有什么区别<br> &nbsp;qry.Connection:=adoconnection1;//这个conn已经设置好的<br> &nbsp;qry.sql.add(sql);<br> &nbsp;result:=qry.open;<br>end;<br>这个函数里的qry即一个TAdoquery对象,如果我没看错的话,<br>你这个函数应该是编译不过去的,要报错的,改成:<br>function ExecSql(Sql:string):TDataSet;<br>var qry:TAdoquery;<br>begin<br> &nbsp;qry:=Tadoquery.create(nil);//是用nil呢?还是self?还是application?有什么区别<br> &nbsp;qry.Connection:=adoconnection1;//这个conn已经设置好的<br> &nbsp;qry.sql.add(sql);<br> &nbsp;qry.open;<br> &nbsp;result:=qry;<br>end;<br>其实这个返回的TDataSet就是qry,而在这个函数中qry是未被释放的!
 
呵呵,我临时写的,代码没有调试,呵呵
 
建议你这样写:<br>function glbOpenQuery(var q: TAdoquery; SQLText: wideString): Boolean;<br>这个带返回数据集的。。。<br>function glbExecSQL(var q: TAdoquery; SQLText: wideString): Boolean;<br>这个仅执行SQL的。。。<br>也许更好一些,不论从理解还是使用上。。。
 
谢谢各位富翁!那我的这个 <br>procedure UseDataset2;<br>begin<br> &nbsp;showmessage(inttostr(execsql('select * from sysobjects').recordcount));<br> &nbsp;//那这个呢?dataset是不是释放掉了<br>end;<br>那这个过程就不能这样调用了?
 
晕4,dataset根本就未创建,你要释放什么呢?<br>形参和实参要搞搞清楚。。。<br>你只要释放qry就可以了,这才是你真正创建的。。。
 
必须free。。
 
to:terryapp<br>dataset在我的第二个测试中已经创建了<br>另,不能在execsql函数中free掉qry,如果free了,我返回的dataset就是nil了,我还调用什么呢
 
多人接受答案了。
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
I
回复
0
查看
556
import
I
I
回复
0
查看
565
import
I
后退
顶部