我正在使用RAD Studio XE-5创建Android应用程序,但最近偶然发现了一个令人费解的错误。 TStringList.AddObject引发以下异常:

Project Project3.apk raised exception class Segmentation fault (11).


我的代码是这个

procedure TMainForm.FormCreate(Sender: TObject);
var
    list: TStrings;
begin
   list := TStringList.Create;
   list.AddObject('Joe', TObject(1)); // This is where exception is raised
   list.AddObject('Hans', TObject(2));
end;


这段代码在32位Windows目标上可以正常运行,但是在我的Nexus 7上运行(以调试模式)时会引发上述异常(当我不使用TStringList.AddObject时运行良好)。如果我在未调试的情况下运行该应用,则它会在Nexus上关闭。

这是Delphi Android的已知问题/局限性吗?是否有解决方法或建议的方法来获得相同的结果(不仅针对此玩具示例,而且通常使用AddObject)?

最佳答案

整个编程风格是Delphi 7时代的做事方式。但是自那以后,许多事情已经发生了变化。最具体地说,移动编译器使用ARC,他们将尝试破坏字符串列表中保存的对象。那解释了您看到的错误。

另一个更改是D2009中添加的对泛型的支持。现在,您应该为该任务使用类型安全的通用容器,而不是字符串列表。周围有很多,但让我们用Generics.Collections的内置类展示一个示例。

您需要创建一个列表元素类型。它包含一个字符串和一个整数。

type
  TMyItem = record
  public
    Name: string;
    Age: Integer;
  end;


让我们以一种简单的方式来制作新的:

function NewMyItem(const Name: string; const Age: Integer): TMyItem;
begin
  Result.Name := Name;
  Result.Age := Age;
end;


然后让我们列出它们:

var
  List: TList<TMyItem>;
....
List := TList<TMyItem>.Create;


现在添加一些项目:

List.Add(NewMyItem('Joe', 1));
List.Add(NewMyItem('Hans', 2));

10-06 03:38