#cocoa
#cocoa
Вопрос:
Я разрабатываю приложение на cocoa.Мне нужно проанализировать XML-файл iTunes большого размера (около 25 Мб).Сейчас я использую следующий фрагмент кода NSDictionary *itunesDatabase = [NSDictionary dictionaryWithContentsOfFile:itunesPath]; Но это немного медленно, Есть ли какой-нибудь более быстрый способ загрузить все данные в словарь??
Комментарии:
1. Вам действительно нужно ускорить это, или проблема в том, что основной поток блокируется во время загрузки файла?
Ответ №1:
Причина, по которой у вас такая низкая производительность, заключается в том, что NSDictionary
все сразу считывается в память. Для большой библиотеки iTunes это может занять много времени и — не стесняйтесь подтвердить это с помощью Activity Monitor — метрическую загрузку памяти. (Это точный технический термин для такого объема памяти)
Альтернативой в этих ситуациях является использование синтаксического анализа XML на основе обратного вызова (обычно известного как синтаксический анализ «SAX»). Они анализируют XML-документы по одному объекту за раз и вызывают ваши методы обратного вызова. В Cocoa NSXMLParser
класс предоставляет эту функциональность. Вы устанавливаете свой класс в качестве его делегата, вызываете parse
метод, и анализатор начинает вызывать методы делегирования при чтении тегов, атрибутов, текста и т.д. В XML-файле.
Теперь это, очевидно, сложнее, чем просто загрузить все в NSDictionary
и обойти результирующее дерево объектов. Вам нужно будет самостоятельно отслеживать информацию о состоянии. И вам придется постепенно «наращивать» свои объекты, поэтому организация ваших классов может быть затруднена.
Однако вы можете игнорировать не интересующий вас XML, и это экономит много памяти. И, в зависимости от того, какие данные вы получаете из iTunes, вы также можете завершить синтаксический анализ, как только получите необходимые данные. Даже если это в конечном итоге займет довольно много времени, по крайней мере, вы сможете показать вашему пользователю индикатор выполнения или какой-либо другой признак того, что ваша программа работает, что намного лучше, чем просто зависать на 10-20 секунд, пока NSDictionary
загружается огромный XML-файл.
Комментарии:
1. Обратите внимание, что NSXMLParser по-прежнему считывает все данные в память одновременно, поскольку
initWithData:
является его назначенным инициализатором.
Ответ №2:
Если вы можете использовать сторонние фреймворки, запустите, а не переходите к EyeTunes. (Лицензия BSD.) Это уровень абстракции вокруг событий Apple для связи с iTunes, и как таковой он не анализирует базу данных XML напрямую (я думаю, прошло некоторое время с тех пор, как я им пользовался), но у вас будет доступ get / set к чему-либо в XML.
Комментарии:
1. Если он использует события Apple, очевидным недостатком является то, что iTunes должен быть запущен, чтобы использовать его
Ответ №3:
Попробуйте использовать libxml:
http://www.cimgf.com/2008/08/18/cocoa-tutorial-libxml-and-xmlreader/
Чтобы минимизировать максимальный объем памяти, создайте и удалите NSAutoreleasePool в своем цикле