XCode 4无法编译非常大的数组,以及有关NSArray / NSString开销的问题

时间:2011-04-17 11:58:40

标签: objective-c ios xcode4 nsarray

我是Objective C和XCode的新手,目前正在开发我的第一款iPhone游戏。游戏必须对超过250,000个单词的拼字游戏字典做一些非常快速的拼写检查,理想情况下足够快,我可以在单个帧中检查100个字符串对单词列表。

我之前在C和actionscript 2中写过这个没有问题,只是使用标准的二进制搜索,但我不确定在Objective C中使用NSString和NSArray等选项实现它的最佳方法。

目前最大的问题是根本不会编译。如果我创建一个填充了NSStrings的NSArray,XCode只会挂起但不会崩溃。我把它编译了大约30分钟没有结果。我正在使用的代码:

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

当wordlist减少到几百个单词时,它会编译并正常工作。

任何人都可以解释为什么会失败,或者提出一个更好的解决方法吗?

接下来我要尝试的是将单词列表分成许多小块;以第一个字母分隔,也许还有字母的数量,但这意味着要重新格式化大量文本文件以进行反复试验,这很可能会碰到同一个墙。

这个问题的另一部分是关于NSArray的速度和NSString的开销的一般查询,与旧式的char指针数组C风格相比。如果NSStrings甚至包含一些额外字节的头或函数指针或其他什么,那么在iPhone应用程序中制作25万个它们可能是错误的,对吧?

任何建议都将非常感谢。

4 个答案:

答案 0 :(得分:5)

真的想要使用数据库 - 内置的SQLite是理想的解决方案。

也就是说,如果您现有C语言解决方案,那就没有理由不能使用它了(就好像你 使用Cocoa类一样)毕竟,尽管你需要谨慎考虑内存利用率,同时考虑到iOS设备的限制。

答案 1 :(得分:4)

消息直接转换为C函数调用,因此您的代码执行此操作:

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

在C中调用函数时,首先将其参数压入堆栈。你不太可能只用几百字就耗尽了堆栈空间,但完全可能只有250,000字。因此,您可能会遇到参数数量或参数数据总大小的编译器限制。

肯定有更好的方法可以做你正在做的事情。至少,使用@ smorgan的建议并从文件中读取列表。更好的方法是使用内存映射文件,这样您就不必一直将整个内容保存在内存中 - 让操作系统处理并将文件的一部分加载到内存中。

答案 2 :(得分:2)

为什么不将单词列表保存在文件中并在启动时读取呢?

而不是将数十万个静态字符串编译到您的应用程序中。

答案 3 :(得分:0)

您可以使用NSAarray +initWithContentsofFile:方法从属性列表文件中读取整个数组来解决编译时问题。

但是,使用带有手动编码二进制搜索的NSArray似乎是错误的工具。只是坚持在Cocoa Touch Foundation课程中,NSSet似乎比NSArray更合适。

在任何情况下,你都可能会担心创建那么多对象的开销;使用现有的C解决方案或数据库作为middaparka说两者听起来都是更好的选择。