Delphi FireMonkey TListBox Исключение AddObject для Android

У меня проблема с добавлением TObject значение для FireMonkey TListBox в Delphi 10.0 Сиэтл

Исключение повышается при сотворении Integer переменная к TObject указатель.

Я попробовал бросить TFmxObject без успеха. В Windows актерский состав работает как шарм, а в Android - исключение.

Вот мой код:

var
  jValue:TJSONValue;
  i,total,id: integer;
  date: string;
begin
  while (i < total) do
  begin
    date := converteDate(jValue.GetValue('date' + IntToStr(i), ''));
    id := StrToInt(jValue.GetValue('id' + IntToStr(i), ''));
    ListBox1.Items.AddObject(date, TObject(id));
    i := i + 1;
  end;
end;

1 ответ

Проблема в том, что на iOS и Android (и скоро Linux), TObject использует автоматический подсчет ссылок для управления временем жизни, и поэтому вы не можете приводить целочисленные значения типа как TObject указатели, как вы можете на Windows и OSX, которые не используют ARC. В системах ARC, TObject указатели должны указывать на реальные объекты, так как компилятор будет выполнять семантику подсчета ссылок на них. Вот почему вы получаете исключение.

Чтобы сделать то, что вы пытаетесь, вам нужно обернуть целочисленное значение внутри реального объекта в системах ARC, например:

{$IFDEF AUTOREFCOUNT}
type
  TIntegerWrapper = class
  public
    Value: Integer;
    constructor Create(AValue: Integer);
  end;

constructor TIntegerWrapper.Create(AValue: Integer);
begin
  inherited Create;
  Value := AValue;
end;
{$ENDIF}

...

ListBox1.Items.AddObject(date, {$IFDEF AUTOREFCOUNT}TIntegerWrapper.Create(id){$ELSE}TObject(id){$ENDIF});

...

{$IFDEF AUTOREFCOUNT}
id := TIntegerWrapper(ListBox1.Items.Objects[index]).Value;
{$ELSE}
id := Integer(ListBox1.Items.Objects[index]);
{$ENDIF}

В противном случае сохраните ваши целые числа в отдельном списке, а затем используйте индексы TListBox элементы как индексы в этот список, когда это необходимо, например:

uses
  .., System.Generics.Collections;

private
  IDs: TList<Integer>;

...

var
  ...
  Index: Integer;
begin    
  ...
  Index := IDs.Add(id);
  try
    ListBox1.Items.Add(date);
  except
    IDs.Delete(Index);
    raise;
  end;
  ...
end;

...

Index := ListBox1.Items.IndexOf('some string');
id := IDs[Index];

Это переносимо на все платформы без использования IFDEFили беспокоиться о ARC.

Другие вопросы по тегам