2011-04-17 42 views
0

我是Objective C和XCode的新手,目前正在開發我的第一款iPhone遊戲。遊戲必須對超過250,000個單詞的拼字遊戲字典進行非常快速的拼寫檢查,理想的速度足夠快,可以在單個框架中檢查100多個字符串與單詞列表。我只寫了一個標準的二進制搜索,但是我不確定在目標C中使用NSString和NSArray等選項來實現這個最好的方法。XCode 4無法編譯一個非常大的數組,以及有關NSArray/NSString開銷的問題

目前最大的問題是它甚至不會編譯。如果我創建一個NSArray填充NSStrings,XCode只是掛起,但不會崩潰。我離開它編譯了大約30分鐘,沒有結果。我正在使用的代碼:

words=[NSArray arrayWithObjects:@"aa", @"aah", ...250,000 words... @"zyzzyvas" ,nil]; 

當wordlist減少到幾百字,它編譯和工作正常。

任何人都可以闡明爲什麼這是失敗的,或建議一個更好的方式去做呢?

接下來我要嘗試的是將詞表分成許多小塊;由第一個字母分隔,也許還有字母數量,但這意味着很多亂七八糟的重新格式化巨大的文本文件的試驗和錯誤,可能很有可能撞到同一堵牆。

這個問題的另一部分是關於NSArray的速度和NSString的開銷與一個老式的char指針,C風格的數組相比的一般性查詢。如果NSString包含頭部或函數指針或其他什麼的額外字節,那麼在iPhone應用程序中創建250,000個字節可能是錯誤的,對嗎?

任何建議都將不勝感激。

回答

4

消息被直接翻譯成C函數調用,所以你的代碼做這個:

words = objc_msgSend(NSArray, @selector(arrayWithObjects:), @"aa", @"aah", ...250,000 more arguments...); 

當一個函數被調用C,它的參數是第一次壓入堆棧。你幾乎不用幾百字就可以用完堆棧空間,但完全有可能達到250,000字。所以,您可能會遇到一些編譯器限制參數數量或參數數據總大小的限制。

確實有更好的方法來做你正在做的事情。至少,使用@ smorgan的建議並從文件中讀取列表。更好的辦法是使用內存映射文件,這樣您就不必一直保留整個內存 - 讓操作系統處理加載並將文件的某些部分加載到內存中。

5

我會真的試圖爲此使用數據庫 - 內置的SQLite是一個理想的解決方案。這就是說,如果你有現有的C語言解決方案,那麼你沒有理由不能使用這個原來的東西(這不像你畢竟使用Cocoa類),儘管考慮到iOS設備的限制,您需要謹慎地考慮內存利用率。

+0

+1 - SQLite數據庫意味着您不必將整個列表加載到內存中。 – 2011-04-17 15:41:35

2

與其將數十萬靜態字符串編譯到您的應用程序中,爲什麼不將單詞列表保存在文件中並在啓動時讀取它?

+0

這是我可能必須考慮的一個選項,雖然我不希望用戶能夠編輯單詞列表,因爲它可能會使得分數作弊。 – Adam 2011-04-17 12:14:04

+0

因此,計算單詞列表的散列,並將散列編譯到應用程序中。然後在運行時讀取之前,重新哈希它確保哈希匹配。 – smorgan 2011-04-17 12:19:32

+1

@Adam除非越獄他們的iOS設備等,否則他們將無法訪問包中的文件或實際上您的應用程序的文檔目錄。 – 2011-04-17 12:23:02

0

通過使用NSAarray +initWithContentsofFile:方法從屬性列表文件中讀取整個數組,您可以解決編譯時問題。

但是,使用NSArray與手工編碼的二進制搜索似乎是錯誤的工具。只要堅持在Cocoa Touch Foundation課程中,似乎比NSArray更適合。

在任何情況下,您可能都很關心創建多個對象的開銷;使用現有的C解決方案或數據庫作爲middaparka說這兩個聽起來像更好的選擇。