跨窗体访问对象时出现内存不能读错误如何解决?(100分)

H

hanmon

Unregistered / Unconfirmed
GUEST, unregistred user!
经常出现这种现象:窗体Form1要弹出一个新窗体Form2,在Form2中对Form1中的对象进行访问,如Form1.Query.但一般没有问题,可是有时却出现内存不能读错误.任何try都不管用.遇到这种情况就不知道怎么办了.
虽然怀疑是Form1和Form2互相use,但并不是问题所在,因为并不是总出现这种现象.
一个简单的跨窗体对象访问并经过调试成功的代码,移植到自己的应用程序上,有时就莫名其妙地出现内存不能读错误,不知道具体错在哪里,很难绕过去,经常在毫无准备的情况下在最平常的地方卡壳,很头疼.
Form1中一个数据表格Dbg1的数据,数据源Qry,希望在Form2中单条记录修改,在Form2中访问Form1.Qry一般是可以的.遇到内存不能读时,只要访问Form1时就报错自动退出应用程序.有一次没有办法,在Form2中加入再加入了一个不显示的数据表格Dbg2,数据源静态地设置到Form1的Qry上,在Form2中就用Dbg2.DataSource.DateSet来替代Form1.Qry才绕过去了.
不知道大家是否遇到这种情况,是否有高手能够给出具体解决方法?
 
通常是自己开发的控件问题
 
自己没有开发控件,也没有使用三方控件.就是两个窗体间的普通调用.我们搞软件的经常在得到用户反馈:出现某某问题了,也许我们在排除了能够想得到的所有解释后.给出回答:你反映的问题绝对不可能出现!事实上很多时候是我们自己错了:绝对不可能出现的问题确确实实地出现了.
我提出的问题或许大家认为不可能出现,但可以告诉大家的是确实出现了!
 
确实会出现/
我在双核电脑上就出现过
打开另外一个窗体有时候会抱错
formshow里包括了读数据库....操作
 
unit2 里面 var form2:tform2;
这句删除
unit2 的type tform2 = class(tform) 里面添加
public
procedure setdata(aquery:tquery);
procedure tform2.setdata(aquery:tquery);
begin
这里操作你的数据
end;

unit1里面使用对象变量
var myform2 :tform2;
begin
myform2 := tform2.create(nil);
myform2.setdata(myquery);
myform2.showmodal;
myform2.free;
end;

再出错,把电脑砸了得了,给分.
 
bsense的建议最具体,不过得分的可能性最小.电脑都砸了,程序当然就报废了.[:D],笑话了,验证看看,该给分的还是不会吝啬的.
 
还是不行,只要访问主调窗口的对象就死.myform2.setdata(myquery);的myquery还是要访问主调窗口的myform1.myquery.改在myform2中加入一个datasource,静态设置期dataset为
myform1.myquery后,在myform2中直接用myform2.datasource.dataset替代myform1.myquery勉强可以,连续执行多次还是会死.且正常状态下打开数据源字段长度(显示宽度)固定,有列名,而此种方式则数据源打开时有时没有数据且连表头都没有,有时字段长度(显示宽度)变化太大,搞不明白.
 
有没有搞错,我让你 做 setdata 的作用是传递一个 dataset 给form2 用, 不要跨单元引用变量,容易导致错误,你倒好 ,还去引用什么myform1.myquery, myform2.datasource.dataset 这些东西 , 应该
type tmyform2 = class(tform)
...
private
FParentQuery:tquery;
procedure setdate(aquery);
begin
Fparentquery := aquery;
end;

一旦你跨 unit 访问变量 ,出现了 tmyform2的 多个对象 就会出错,
 
setdate(aquery);你这个aquery从哪里来?我就要form2中操作记录,form1中当前记录同步变化(就是同一个数据源),setdate过程倒是form2的,但参数aquery你传什么东西进来?
 
不要傻乎乎的在一个窗体的Code里面直接硬编码使用类似下面的代码:
TForm2.Button1Click()
begin
Form1.xxxxxx;
end;

或者在TForm1.Button1Click中写:
Form2.xxxx;
这种编码风格完全不对,如果Form1和Form2是自动创建,并且永远不销毁还差不多,否则容易出现AV错误。正确的方式应该是创建窗体,并传递进来。
 
顶部