2013-10-04 57 views
1

我正在使用RAD Studio XE-5創建Android應用程序,但最近偶然發現了一個令人費解的錯誤。 TStringList.AddObject引發以下異常:TStringList.AddObject不適用於Android(德爾福)

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)?

+1

Android編譯器使用ARC,因此您不能將整數視爲像你在Win32/64中做的那樣。 –

+0

@StefanGlienke這是否意味着我可以在一個類中包裝整數(如Integer在java中),它應該工作? – Daniel

+0

是的,看到這篇博客文章(它談論iOS,但同樣適用於Android):http://blogs.riversoftavg.com/index.php/2013/08/01/using-primitive-types-with-tstrings- in-ios/ –

回答

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)); 
+1

我可以在列表框中使用這個解決方案嗎?我引發這個問題的原始問題是,我試圖在列表框中的每個項目上保存一個Id,而ListBox.Items是類型TStrings。 – Daniel

+0

該問題陳述'TStringList',因此我的答案。您不能在列表框中使用此解決方案。 –

+0

FMX中的ListBox是否支持像VCL中的虛擬模式?如果是這樣,那麼你可以使用一個自定義容器並使ListBox顯示它。否則,只需將字符串添加到ListBox並在需要時使用其項目索引來訪問容器。 –