Monthly Archives: August 2013

AUTOREFCOUNT and the Free Pattern

The more I use the Delphi mobile compiler and its automatic reference counting (ARC), the more I am coming to the conclusion that Embarcadero chose the wrong implementation pattern for the Free code.  Now I am not getting into the pros and cons of ARC here, I am just referring to how the Free method in the ARC compiler is mapped to nil in mobile code.  It should have stayed a Free/DisposeOf method instead.

Why do I think it was mistake?

1.  If Free is used in ARC code, the developer is porting code from other compilers.  He/she wants this behavior.  If the developer is writing from scratch for mobile (and only mobile), he will omit the Free call (or use DisposeOf).  Even worse, for the component developer, the DisposeOf option is not available.  We have to leave the Free call in as the code must work in earlier versions of Delphi.

2. The ARC compiler’s unfortunate decision to output a hint when it encounters a Free call means I usually end up mapping the Free to DisposeOf with very ugly IFDEFs anyway to get rid of the hint, e.g.,

aObject.{$IFDEF AUTOREFCOUNT}DisposeOf;{$ELSE}Free;{$ENDIF}

3. Mapping Free to nil makes destruction of objects non-deterministic from the developer’s point of view.  From the point of view of the program, of course, it is completely deterministic: destruction occurs when there are no more references to the object.  However, from the developer’s point of view, mapping Free to reference = nil is not deterministic, as the call to Free may not do anything!  It is especially bad as the behavior from non-ARC to ARC changes.  Often, I depend on the destruction of an object to notify other objects.  If that destruction doesn’t happen or happens at a different time, bad things can happen.

Objections

Now, there are plenty of objections you can make to this.

ARC is supposed to make our code more robust, and the Free method bypasses that safety.  However, Embarcadero supplies the DisposeOf method to get around that safety anyway!  Why couldn’t the Free call have stayed the method for forcing destruction?

Disposing of the object when there are still references can cause access violations!  Well, maybe… and maybe not.  The TComponent memory management architecture (using notification) means that there can be multiple references to a component, but that the destruction of a component can clean them all up.  And I would argue that I *want* to see these problems otherwise.  I am porting from a non-memory managed compiler.  If I haven’t cleaned this up properly on non-ARC, it is a bug.  It should be a bug here.

What happens in practice, except for simple classes, is that the Destroy code gets called at an unexpected moment and then causes access violations or other unexpected behavior that the developer did not expect.  It is very difficult to debug this late destruction behavior.

So to close, the Free method should have stayed Free! (I feel very patriotic for some reason right now 🙂 )  Not only would it have made the look of the code much better (without ugly IFDEFs), the behavior of the code between compilers would have stayed more alike and easier to debug. 

 

Listening is Learning

Quick note: On August 14th, Ray Konopka had his Seeing is Believing: Data Visualization in Multi-Device Apps with RAD Studio.  I highly recommend watching this webinar.  It is one of best webinars for Delphi and FireMonkey you can watch.  Unlike some webinars that are more marketing than material (or that the title of this webinar even suggests 🙂 ), the webinar is dense with information and presented in a very clear and logical format.  Ray wrote one of the best early Delphi books and it shows.  This guy knows his stuff.  I know I learned a lot about FireMonkey component development from watching this webinar.  Highly recommended, thumbs up, and five stars! 🙂

Disclaimer: I have worked with Ray on Raize Software’s Inspex component. 

Using Primitive Types with TStrings in iOS

Problem

One of the unwelcome surprises with coding in Delphi for iOS is that you cannot store primitive types (integer, string, single, etc) in TStrings.Objects.  Usually, I am storing TObjects in the TStrings but occasionally it needs to be a primitive type (such as a score).   I would never do this for components but for programs where I know exactly what I place in the TStrings, I find nothing wrong with this and it is incredibly useful.

But with Delphi for iOS, when you try:

ListBox1.Items.AddObject('Tom', TObject(100));

It blows up.  In retrospect (and with a little digging with the debugger), it is obvious why you cannot.  With an automatic reference counting compiler, any new references to an object means that the compiler inserts calls to __ObjAddRef when you add an object to the Listbox’s list.  Since the TObject(100) is not a real object, kaboom!

Now if Delphi was a “rooted” language (i.e., even primitive types have a TObject equivalent, similar to .NET or java), this would not be a problem.  The primitive would automatically be boxed and unboxed as needed to store it inside a TObject.  However, Delphi is not a rooted language, at least not yet.   Well, the technique is so useful I was unwilling to give it up.

Solution

By using generics and class operators, I have come up with a generic class for boxing and unboxing primitive types (actually any type) which I find pretty slick.  Before I get into the details, I want to show how you would use it.  To add a primitive to a TStrings, just use the TBoxXXX cast where XXX is the primitive type name:

ListBox1.Items.AddObject('Hello', TBoxInteger(10));
ListBox1.Items.AddObject('World', TBoxString('It is a nice day'));
ListBox1.Items.AddObject('How', TBoxDouble(20.23334));

To unbox back to the primitive type, it is a little more complicated.  First, you cast your TObject back to its TBoxXXX type and then you can cast it either explicitly or implicitly back to the primitive type:

var
  i: Integer;
begin
  i := TBoxInteger(ListBox1.Items.Objects[0]);
  ShowMessage(i.ToString);
end;

Easy as can be! 🙂  The one wrinkle is that the IndexOfObject method will no longer work because the method compares the TObject to the TBoxInteger object and not its value.  To handle that case, I have added an IndexOf class method:

ShowMessage(TBoxInteger.IndexOf(ListBox1.Items, 100).ToString);

Code

So how does the code work?  The whole trick is to define a generic boxing class.  This class contains a private field containing the primitive value.  It then defines implicit and explicit conversions from the primitive to the boxing object and back.  It adds the previously mentioned IndexOf method and defines the Equal class operator to make it work.  The full declaration is thus:

TRSBoxPrimitive<T> = class(TObject)
{ Purpose: To provide a simple class for boxing and unboxing a primitive type
Note: this class is only for use by AUTOREFCOUNT compilers }
private
  { private declarations }
  FValue: T;
protected
  { protected declarations }
public
  { public declarations }
  constructor Create( const V: T );
  class operator Equal(a,b: TRSBoxPrimitive<T>): Boolean;
  class operator NotEqual(a,b: TRSBoxPrimitive<T>): Boolean;
  class function IndexOf( const Strings: TStrings; a: T ): Integer;
  class operator Implicit(a: T): TRSBoxPrimitive<T>; 
  class operator Implicit(a: TRSBoxPrimitive<T>): T;
  class operator Explicit(a: T): TRSBoxPrimitive<T>; 
  class operator Explicit(a: TRSBoxPrimitive<T>): T; 
end; { TRSBoxPrimitive<T> }

When you type TBoxInteger(100), the Explicit(a: T): TRSBoxPrimitive<T> method is called:

class operator TRSBoxPrimitive&lt;T&gt;.Explicit(a: T): TRSBoxPrimitive&lt;T&gt;;
begin
  result := TRSBoxPrimitive&lt;T&gt;.Create(a);
end;

The line assigning the boxed value back to an integer calls the Implicit(a: TRSBoxPrimitive<T>): T method:

class operator TRSBoxPrimitive&lt;T&gt;.Implicit(a: TRSBoxPrimitive&lt;T&gt;): T;
begin
  result := a.FValue;
end;

The final code creates primitive boxing types from the generic type:

TBoxInteger = TRSBoxPrimitive&lt;Integer&gt;;
TBoxString = TRSBoxPrimitive&lt;String&gt;;
TBoxDouble = TRSBoxPrimitive&lt;Double&gt;;
...

The code takes advantage of the fact that the TBoxXXX classes are reference counted and will be automatically destroyed.  Otherwise, this code would leak like a sieve!  A cool bonus with this code is that the boxing allows primitive types that would not usually fit in the size of TObject.

Hopefully, this code is as useful to you as it is to me.  The full code is available here for you to use as you see fit (but please keep the attribution and let me know if you improve it)

Happy CodeSmithing!