showmodal显示窗体,关闭时内存报错。请问各位知道原因么?
创建的时候用的
if not assigned(form1) then
begin
form1:=Tform1.create(application);
form1.showmodal;
end;
关闭时在close里写
action:=cafree;
form1:=nil;
各位帮忙看看。
创建的时候用的
if not assigned(form1) then
begin
form1:=Tform1.create(application);
form1.showmodal;
end;
关闭时在close里写
action:=cafree;
form1:=nil;
各位帮忙看看。
解决方案 »
- 如何在局域网内自动搜索TIdUDPServer
- printer 打印问题 第一次有内容 再次点击按钮打印就是一张空白 求救 在线
- DOC、RTF或者html文档怎么存入数据库中?
- 哪里有VC++的工具下载?????
- 网页与程序如何联系?各位帮帮了!
- 在下准备做一个24的程序,看看大家有什么好的算法!!(四个数的排列已经得到)!
- 我想讓qrmemo顯示在報表的最後面,並且自動調整高度,怎麼做?在線等待!!!
- 怎样跳出一个过程?
- 1.如何使SQL的UPDATE语句把空的'N'类型字段当做 0 处理.
- 请问:如何在Delphi中实现双击打开相应文件
- 招DELPHI软件开发工程师
- 关于TQuery的编辑状态的问题。
action:=cafree;
form1:=nil; 谁的close事件
if not assigned(form1) then
begin
form1:=Tform1.create(application);
form1.showmodal;
end;
在form2的close事件里写
action:=cafree;
form1:=nil; 没有问题
form1:=nil; 可以不写
try
Showmodal;
finally
Free;
end;
if not assigned(form1) then //不要用這種方法判斷。 form1:=nil; // 在類的關閉事件裏,不要帶入引用變量。
不過你上面的代碼應該是沒有錯的。 你貼出錯來,應該是別的地方引起的。
form1.showmodal;
//直接跟free就好了
//Showmessage('什么时候下去'); 你会发现窗体关闭后才往下走
form1.free;
要寫在ondestroy事件里面
begin
inherited;
form1:=nil;
end;設定cafree後-----調用release--->free---->構造函數Destroy,這里會去遍歷application,執行removecomponent,將自己從components屬性list中移除。
所以你在之后設定form1:=nil,執行free時,不會觸發destroy,會造成components無法被正確維護,在之后的訪問過程中,就出現地址訪問非法的問題。所以應該寫在ondestroy里面。建議在create對象時,能不傳參數就不傳,傳nil。這樣效能上面肯定比較好,因為不必再去維護owner.components。
像下面的 Free 能触发 destructor Destroy 么?会出任何现访问错误么? form1 := nil;
with TForm1.Create(Application) do
try
ShowModal;
finally
end;
...procedure TForm1.FormClose(Sender: TObject);
begin
form1 := nil; {*}
Free; { 已经在设计期使 OnClose = FormClose }
end;如果前面用 form1 := TForm1.Create(Application),那么*那句会造成什么影响?或者program Project1;uses
Forms,
Unit1;procedure CreateMainForm;
var t: Cardinal;
begin
Application.CreateForm(TForm1, t);
end;begin
Application.Initialize;
CreateMainForm;
Application.Run;
end.
unit Unit1;interfaceuses
Forms;type
TForm1 = class(TForm)
end;implementation{$R *.dfm}end.
{==== Unit1.dfm ====}
object blah: TForm1
end像这样的程序能正确执行么?会有什么诸如Application无法正确维护出现访问错误的不良后果么?
btw,注意在 Unit1 中连 var Form1: TForm1 的声明都没有
1、先搞清楚我要说的是什么,application只是一个例子,因为是作为参数传进取,只要是Tcomponent类型的!
2、把相关源代码先看清楚;
3、要驳倒我的观点,请拿出具有可比性的东西!不要在没搞清问题前就在这“发飚”,我可没那么多时间陪你 耍
答案是:Destroy是Destroy,FormDestroy是FormDestroy,两者没关系,OnDestroy里写一句inherited什么都不会发生。delphi的对象不需要靠外部变量去维护,它自己可以通过Self指针正确处理。后面我举的几个例子就是为了说明,不论什么何时设定 form1:=nil 甚至不要form1这个变量,都不会影响vcl的运作机制。所以你说的一堆不会触发这个那个,什么不会被正确维护、地址访问错误之类的都是扯淡,谁希罕跟您“发飚”么?
1: if not assigned(form1) then //不要用這種方法判斷。
为什么不能用这种方法判断?
2:我的程序中有第三方控件,是不是有可能是因为第三方控件的原因才导致内存错误?
3:如果是show窗体的话。该怎么释放?
2:不大可能
3:OnClose事件里写个Realse;方便简单
和
if Form1<>nil then
Assigned是判断指针所指向的内容是否为空。如果Form1指向的内容(即对象)被释放,但没有把Form1赋成nil的话,则会出现下列的情况:
Assigned(Form1)返回false
而Form1<>nil返回true
可见是不等价的,如果Form1是一个全局变量的话,释放Form1用Form1.free是不严格的,应该用FreeAndNil(Form1);
2:if not assigned(form1) then form1:=Tform1.create(application) 和 with TForm1.Create(self)的区别。
1. 删掉编译好的dcu,用 dcc32.exe -q *.pas -z -$D- 重新编译
2. 如果是关于with,随便找本书应该都有说;如果是问TForm.Create(AOwner: TComponent)的差别,那么见vcl源代码constructor TComponent.Create(AOwner: TComponent);
begin
FComponentStyle := [csInheritable];
if AOwner <> nil then AOwner.InsertComponent(Self);
end;也就是说,当指定为AOwner的控件被释放的时候,该控件也被释放了。虽然一般情况下ShowModal里不会放什么奇怪的代码,Create(Self/Application/nil)看起来没什么差别(一般都是在窗体事件中,Self指向的是一个TForm的继承对象),但是像下面这段代码就可以挂掉用Create(Self)的程序(由于模式窗体的作用,程序将没法再得到响应):{Unit1.pas}
...
implementationuses
Unit2;procedure TForm1.Button1Click(Sender: TObject);
begin
if(not Assigned(Form2))then
Form2 := TForm2.Create(Application);
Form2.Show;
end;=================================================
{Unit2.pas}
...
implementationuses
Unit3;procedure TForm2.Button1Click(Sender: TObject);
begin
with TForm3.Create(Self) do { 换成Application/nil则没问题 }
try
ShowModal;
finally
Free;
end;
end;=================================================
{Unit3.pas}
...
implementationuses
Unit2;procedure TForm3.Button1Click(Sender: TObject);
begin
FreeAndNil(Form2);
end;ps:使用环境为d7。如果设计vcl的时候考虑到的话,也有较复杂的办法可以避免这种情况发生,不知道后面版本的delphi有没有在vcl中“修正”这个“bug”
你自己试试有没有Form1赋成nil的结果再来说
Assigned(p) 和 p<>nil 不等价,按照你的说法,会出现 Assigned(Form1)为False 并且 Form1<>nil为True 的情况
还是你构造一个这种情况出来吧要不,我这儿给您一段代码,您亲自试试看自己是不是胡说?procedure TForm1.Button1Click(Sender: TObject);
const
B2S : array[Boolean]of string = ('False', 'True');
var
o : TObject;
begin
o := TButton.Create(nil);
o.Free;
Memo1.Lines.Add(B2S[Assigned(o)]);
Memo1.Lines.Add(B2S[o<>nil]);
end;