Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: Freeing Controls From a FireMonkey form on Android (and iOS)


This question is answered.


Permlink Replies: 4 - Last Post: Aug 31, 2015 5:42 PM Last Post By: Free Dorfman
Free Dorfman

Posts: 139
Registered: 2/4/12
Freeing Controls From a FireMonkey form on Android (and iOS)  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 31, 2015 1:49 PM
I want to dynamically Create & Free controls in my XE8 FireMonkey app.

It works for Windows, not Android:
:
type
TForm1 = class(TForm)
:
:

private
R: TRectangle;
end;
:
:
procedure TForm1.Button1Click(Sender: TObject);
begin
R := TRectangle.Create(Self);
R.Parent := Self;
R.SetBounds(10,100,100,30);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
R.Free;
R := nil;
end;
:
This works fine under Windows, and the TRectangle disappears. Under Android, Button2Click doesn't seem to do anything.
:
Any thoughts?
:
:
Thanks!
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Freeing Controls From a FireMonkey form on Android (and iOS)  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 31, 2015 2:26 PM   in response to: Free Dorfman in response to: Free Dorfman
Free wrote:

It works for Windows, not Android:

Welcome to ARC programming. Remember that under ARC, TObject.Free() does
not actually free the object from memory, it merely nils the variable that
Free() is being called on, thus removing that reference to the object. The
object is not freed from memory until all references to it have been cleared.
There are several references to the object inside of the Owner and Parent
that you have assigned to it, which are still referencing the object after
you have cleared your own reference to it. Thus the object stays alive.
To work around that, you need to either:

1. remove those extra references manually:

procedure TForm1.Button2Click(Sender: TObject);
begin
  {$IFDEF AUTOREFCOUNT}
  R.Parent := nil;
  R.Owner.RemoveComponent(R);
  {$ELSE}
  R.Free;
  {$ENDIF}
  R := nil;
end;


Or else call the object's Dispose() method (which I do not recommend, but
it is an option nontheless):

procedure TForm1.Button2Click(Sender: TObject);
begin
  {$IFDEF AUTOREFCOUNT}
  R.Dispose;
  {$ELSE}
  R.Free;
  {$ENDIF}
  R := nil;
end;


--
Remy Lebeau (TeamB)
Free Dorfman

Posts: 139
Registered: 2/4/12
Re: Freeing Controls From a FireMonkey form on Android (and iOS)  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 31, 2015 3:50 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:
Free wrote:

It works for Windows, not Android:

Welcome to ARC programming. Remember that under ARC, TObject.Free() does
not actually free the object from memory, it merely nils the variable that
Free() is being called on, thus removing that reference to the object. The
object is not freed from memory until all references to it have been cleared.
There are several references to the object inside of the Owner and Parent
that you have assigned to it, which are still referencing the object after
you have cleared your own reference to it. Thus the object stays alive.
To work around that, you need to either:

1. remove those extra references manually:

procedure TForm1.Button2Click(Sender: TObject);
begin
  {$IFDEF AUTOREFCOUNT}
  R.Parent := nil;
  R.Owner.RemoveComponent(R);
  {$ELSE}
  R.Free;
  {$ENDIF}
  R := nil;
end;


Or else call the object's Dispose() method (which I do not recommend, but
it is an option nontheless):

procedure TForm1.Button2Click(Sender: TObject);
begin
  {$IFDEF AUTOREFCOUNT}
  R.Dispose;
  {$ELSE}
  R.Free;
  {$ENDIF}
  R := nil;
end;


--
Remy Lebeau (TeamB)

That worked just fine.

Two quick follow ups:

(1) When is AUTOREFCOUNT defined? Is this an Android/iOS thing? Should your approach (not the Dispose one) work on iOS too?

(2) Why wouldn't XE in effect do the same thing in the .Free method? Could I create a routine called FreeObject that wraps this code? Or - as I now suspect, it's really a matter of knowing & freeing ALL references to that object -- which will be (to some extent) driven by each particular instance (is it on a form, is it an object of a list, etc)?

Thanks Again!

Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Freeing Controls From a FireMonkey form on Android (and iOS)
Correct
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 31, 2015 4:39 PM   in response to: Free Dorfman in response to: Free Dorfman
Free wrote:

(1) When is AUTOREFCOUNT defined?

It is defined in the mobile compilers, which use ARC. See the documentation
for the full list of available conditionals in each compiler:

http://docwiki.embarcadero.com/RADStudio/Seattle/en/Conditional_compilation_(Delphi)

Is this an Android/iOS thing?

Yes.

Should your approach (not the Dispose one) work on iOS too?

Yes.

(2) Why wouldn't XE in effect do the same thing in the .Free method?

The ARC compilers replace a call to Free() with a nil assignment instead.
In other words, under ARC, this statement:

obj.Free;


Is identical to this statement:

obj := nil;


Could I create a routine called FreeObject that wraps this code?

You could, but it will make your code ugly having to put that all over the
place, remember when to use it, and whether it will even be affective to
begin with. You don't want to just rip out an object from memory if someone
else is still using it. That is what ARC is meant to prevent.

Or - as I now suspect, it's really a matter of knowing & freeing ALL
references to that object -- which will be (to some extent) driven by
each particular instance (is it on a form, is it an object of a list,
etc)?

Yes.

--
Remy Lebeau (TeamB)
Free Dorfman

Posts: 139
Registered: 2/4/12
Re: Freeing Controls From a FireMonkey form on Android (and iOS)  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 31, 2015 5:42 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy,

Thank you so much!
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02