Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I use .Create(Nil) instead of .Create(Application)

I have a unit which has a variable of TComponent, I create this component on Initialization of the unit like following :

var
  XComp: TComponent;
.
.
.
.

initialization
begin
  XCom := TComponent.Create(Application);
end;

after installing the unit when I close Delphi it gives me an Access Violation error message (EAccessViolation)

but when I changed my creator to be as following

initialization
begin
  XCom := TComponent.Create(nil);
end;

everything went fine...I would like to know the difference? and what is the better?

note : the error only appears when closing the delphi (means at design time).

Thanks.

like image 931
user1512094 Avatar asked Aug 04 '12 09:08

user1512094


2 Answers

When you use

XCom := TComponent.Create(Application);

you make Application the owner of XCom. When the application is terminating it will take care of destroying XCom, since it is the owner.

When you do

XCom := TComponent.Create(nil);

nobody is owner of XCom and you have to free it yourself when the application terminates.

You probably got the exception because you manually freed XCom and then Application tried to free XCom as well.

like image 163
Birger Avatar answered Oct 21 '22 09:10

Birger


Basically both are allowed and it should not result in an AV even if you have code like this:

MyComp := TMyComp.Create(Application);
try
  {...}
finally
  MyComp.Free;
end;

This is because a properly coded component will remove itself from its owner's components list when it is being destroyed.

I think the problem here might be that the component was already freed by the application object and later on some code tries to access it. Maybe there is a finalize section in your code, that does it? Or you might have mixed objects and interfaces and reference counting got you.

To debug your problem, you could run the IDE in the debugger by setting your package's "host application" to Delphi (C:\Program Files\\BDS\\Bin\bds.exe). and set a breakpoint in your component's destructor. That way you will find out where it is being freed and also where the AV occurs.

like image 26
dummzeuch Avatar answered Oct 21 '22 09:10

dummzeuch