XCode 4 не в состоянии скомпилировать очень большой массив, и вопросы о накладных расходах NSArray / NSString - PullRequest
0 голосов
/ 17 апреля 2011

Я новичок в Objective C и XCode, сейчас работаю над своей первой игрой для iPhone.Игра должна выполнить очень быструю проверку орфографии по словарю скрэббл из более чем 250 000 слов, в идеале достаточно быструю, чтобы я мог проверять более 100 строк по списку слов в одном кадре.

Я уже писал об этом раньше в C и ActionScript 2 без проблем, просто используя стандартный двоичный поиск, но я не уверен, что это лучший способ реализовать это в Objective C с такими параметрами, как NSString и NSArray.

Самая большая проблема на данный момент заключается в том, что он даже не будет компилироваться.Если я создаю NSArray, заполненный NSStrings, XCode просто зависает, но не падает.Я оставил компиляцию около 30 минут безрезультатно.Код, который я использовал:

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

Когда список слов сокращается до пары сотен слов, он компилируется и работает нормально.

Может кто-нибудь пролить свет на причину сбоя илипредложить лучший способ сделать это?

Следующее, что я собираюсь попробовать, это разбить список слов на множество более мелких частей;разделенные первой буквой и, возможно, также количеством букв, но это означает, что вам нужно много переформатировать огромные текстовые файлы для проб и ошибок, которые вполне могут попасть в ту же стену.

Другая часть этогоВопрос - это общий запрос о скорости NSArray и издержках NSString по сравнению со старомодным массивом указателей на символы в стиле C.Если строки NSString содержат даже несколько дополнительных байтов заголовков или указателей функций или чего-то еще, создание 250 тысяч из них в приложении для iPhone, вероятно, является неправильным решением, верно?

Любые предложения вообще будут приняты с благодарностью.

Ответы [ 4 ]

5 голосов
/ 17 апреля 2011

Я бы действительно испытал бы искушение использовать для этого базу данных - встроенный SQLite является идеальным решением.

Тем не менее, если у вас есть существующее решение C под рукой, нет никаких причин, по которым вы не можете использовать это как есть (это не так, как если бы у вас было для использования классов Какао после все), хотя вам нужно будет осторожно подходить к использованию памяти, учитывая ограничения устройств iOS.

4 голосов
/ 17 апреля 2011

Сообщения переводятся непосредственно в вызовы функций C, поэтому ваш код делает это:

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

Когда функция вызывается в C, ее параметры сначала помещаются в стек. Маловероятно, что вам не хватает места в стеке всего за несколько сотен слов, но вполне возможно при 250 000 слов. Таким образом, вы, вероятно, столкнулись с каким-то ограничением компилятора либо по количеству параметров, либо по общему размеру данных параметров.

Есть определенно лучшие способы делать то, что ты делаешь. По крайней мере, используйте предложение @ smorgan и прочитайте список из файла. Лучше было бы использовать файл с отображением в памяти, чтобы вам не приходилось постоянно хранить всю вещь в памяти - пусть ОС обрабатывает загрузку и загрузку частей файла в память за вас.

2 голосов
/ 17 апреля 2011

Вместо того, чтобы компилировать сотни тысяч статических строк в ваше приложение, почему бы не сохранить список слов в файле и не прочитать его при запуске?

0 голосов
/ 17 апреля 2011

Вы можете решить проблему времени компиляции, используя метод NSAarray +initWithContentsofFile: для чтения всего массива из файла списка свойств.

Но использование NSArray с ручным двоичным поиском кажется неправильным инструментом. * Просто придерживаясь классов Cocoa Touch Foundation, NSSet кажется более подходящим, чем NSArray.

В любом случае вы, вероятно, правы, когда беспокоитесь о накладных расходах на создание такого количества объектов; используя ваше существующее решение C или базу данных, как сказал middaparka, оба звучат как лучшие варианты.

...