简体   繁体   中英

Using TStringList.AddObject in Delphi Android FMX

I have a FMX TCombobox in my Delphi 10.3.3 app that I'm compiling for Android. I had previously researched the subject and found Using Primitive Types with TStrings in iOS . I downloaded BoxPrimitives.pas and the code below, compiled sucessfully under Delphi 10.3.3.

uses BoxPrimitives;

{$ifdef ANDROID}
cbGender.Items.AddObject('Male', TBoxInteger(1));
cbGender.Items.AddObject('Female', TBoxInteger(0));
{$else}
cbGender.Items.AddObject('Male', TObject(1));
cbGender.Items.AddObject('Female', TObject(0));
{$endif}

Now I've opened that source code in Delphi 10.4.1, and the BoxPrimitives.Pas no longer compiles.

[DCC Error] BoxPrimitives.pas(46): E2123 PROCEDURE, FUNCTION, PROPERTY, or VAR expected

The general question then is: What changed in Delphi 10.4 that's preventing it from compiling? And more specifically: Is there a way to use AddObject with a TCombobox in Android in Delphi 10.4?

In RAD Studio 10.4, Embarcadero decided to remove ARC for object lifetime management on its mobile platforms.

What's New in RAD Studio 10.4 Sydney

Unified Memory Management

  • Delphi memory management is now unified across all supported platforms - mobile, desktop, and server - using the classic implementation of object memory management . Compared to Automatic Reference Counting (ARC), this offers better compatibility with existing code and simpler coding for components, libraries, and end-user applications. The ARC model remains for string management and interface type references for all platforms.

  • For C++, this change means that the creation and deletion of Delphi-style classes in C++ follow normal memory management just like any heap-allocated C++ class, significantly reducing complexity.

The correct way to detect when ARC object lifetime management is being used, across all Delphi compiler versions and platforms, is to use {$IFDEF AUTOREFCOUNT} . This is even mentioned in the BoxPrimitives.pas unit:

this class is only for use by AUTOREFCOUNT compilers

For example:

{$ifdef AUTOREFCOUNT}
uses BoxPrimitives;
{$endif}

{$ifdef AUTOREFCOUNT}
cbGender.Items.AddObject('Male', TBoxInteger(1));
cbGender.Items.AddObject('Female', TBoxInteger(0));
{$else}
cbGender.Items.AddObject('Male', TObject(1));
cbGender.Items.AddObject('Female', TObject(0));
{$endif}

...

var Value: Integer;
{$ifdef AUTOREFCOUNT}
Value := TBoxInteger(cbGender.Items.Objects[index]);
{$else}
Value := Integer(cbGender.Items.Objects[index]);
{$endif}

That being said, I would probably take this a step further, by editing BoxPrimitives.pas to surround its code with {$IFDEF AUTOREFCOUNT} ... {$ELSE} ... {$ENDIF} , and then in the {ELSE} section define TBoxInteger (and other types) as simple aliases, eg:

interface

{$ifdef AUTOREFCOUNT}

uses
  Classes, Types, Generics.Defaults;

type
  TRSBoxPrimitive<T> = class(TObject)
    ...
  end;

  TBoxInteger = TRSBoxPrimitive<Integer>;
  TUnboxInteger = TBoxInteger;
  ...

{$else}

type
  TBoxInteger = TObject;
  TUnboxInteger = Integer;
  ...

{$endif}

implementation

{$ifdef AUTOREFCOUNT}

...

{$endif}

end.

Then you wouldn't need to {$IFDEF} your AddObject() calls at all, just use TBoxInteger and TUnboxInteger unconditionally on all platforms, eg:

// look ma, no IFDEF's!
uses BoxPrimitives;

cbGender.Items.AddObject('Male', TBoxInteger(1));
cbGender.Items.AddObject('Female', TBoxInteger(0));
...
var Value: Integer;
Value := TUnboxInteger(cbGender.Items.Objects[index]);

Based on Dalija's comment, the answer then is to modify the code so it looks like this:

{$if defined(Android) and (CompilerVersion < 34)}
uses BoxPrimitives
{$endif}

{$if defined(Android) and (CompilerVersion < 34)}
cbGender.Items.AddObject('Male', TBoxInteger(1));
cbGender.Items.AddObject('Female', TBoxInteger(0));
{$else}
cbGender.Items.AddObject('Male', TObject(1));
cbGender.Items.AddObject('Female', TObject(0));
{$endif}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM