2

我正在使用 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)?

4

2 回答 2

4

在 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));
于 2013-10-04T08:20:26.533 回答
0

我不知道,为什么 Stefan Glienke 没有写他们的评论作为答案,但这是一个非常好的另一个答案:

请参阅此博客文章(它谈论 iOS,但同样适用于 Android):http: //blogs.riversoftavg.com/index.php/2013/08/01/using-primitive-types-with-tstrings-in-ios /

建议是创建一个新的包装类来将 Integer 包装到 TObject 中,为它们制作类运算符 Implicit 和 Explicit 以轻松转换,并使用对此类的强制转换而不是将 Integers 强制转换为 TObject 并返回到 Integer。它最大限度地减少了所需的代码更改。

于 2020-04-27T21:54:15.550 回答