Ответ 1
Вся эта информация содержится в карте ссылок, если у вас есть терпение для просеивания через нее (для крупных приложений она может быть довольно большой). На карте ссылок есть список всех библиотек, их объектных файлов и всех символов, которые были упакованы в ваше приложение, все в тексте, удобном для чтения. Обычно проекты не настроены для их генерации по умолчанию, поэтому вам придется быстро сменить файл проекта.
Изнутри Xcode:
- В разделе "Настройки сборки" для вашей цели найдите "карту"
- В приведенных ниже результатах в разделе "Связывание" установите "Write Link Map File" в "Yes"
- Обязательно обратите внимание на полный путь и имя файла, перечисленные в разделе "Путь к файлу карты ссылок"
В следующий раз, когда вы создадите приложение, вы получите карту ссылок, сбрасываемую на этот путь к файлу. Обратите внимание, что путь относится к местоположению вашего приложения в папке DerivedData (обычно ~/Library/Developer/Xcode/DerivedData/<your-app-name>-<random-string-of-letters-and-numbers>/Build/Intermediates/...
, но YMMV). Поскольку это просто текстовый файл, вы можете прочитать его с помощью любого текстового редактора.
Содержимое карты ссылок разделено на 3 раздела, из которых 2 будет иметь отношение к тому, что вы ищете:
- Объектные файлы: этот раздел содержит список всех объектных файлов, включенных в ваше окончательное приложение, включая ваш собственный код и код любых сторонних библиотек, которые вы включили. Важно отметить, что каждый объектный файл также содержит библиотеку, в которой он появился;
- Разделы: этот раздел, не относящийся к вашему вопросу, содержит список сегментов процессора и их разделов;
- Символы: этот раздел содержит необработанные данные, которые вас интересуют: список всех символов/методов с их абсолютным местоположением (т.е. адрес на карте памяти процессора), размер и, самое главное, ссылку на их содержащий объектный модуль (в столбце "Файл" ).
Из этих необработанных данных у вас есть все необходимое для расчета необходимого размера. Из № 1 вы видите, что для каждой библиотеки существует N возможных составных объектных модулей; из # 2 вы видите, что для каждого объектного модуля есть М возможных символов, каждый из которых занимает размер S. Для любой данной библиотеки ваш грубый порядок размера будет чем-то вроде O (N * M * S). Это только для того, чтобы дать вам представление о компонентах, которые вошли бы в ваши фактические вычисления, это не какая-то полезная формула. Для выполнения самого расчета, мне жаль говорить, что я не знаю каких-либо существующих инструментов, которые сделают необходимую обработку для вас, но учитывая, что карта ссылок - это всего лишь текстовый файл, с малой магией script и изобретательность вы можете построить script для тяжелого подъема.
Например, у меня есть небольшой примерный проект, который ссылается на следующую библиотеку: https://github.com/ColinEberhardt/LinqToObjectiveC (сам образец проекта - из хорошего учебника по ReactiveCocoa, здесь: http://www.raywenderlich.com/62699/reactivecocoa-tutorial-pt1), и я хочу знать, сколько места он занимает. Я создал карту ссылок, TwitterInstant-LinkMap-normal-x86_64.txt(она запускается в симуляторе). Чтобы найти все объектные модули, включенные библиотекой, я делаю следующее:
$ grep -i "libLinqToObjectiveC.a" TwitterInstant-LinkMap-normal-x86_64.txt
который дает мне это:
[ 8] /Users/Smyrl/Library/Developer/Xcode/DerivedData/TwitterInstant-ecppmzhbawtxkwctokwryodvgkur/Build/Products/Debug-iphonesimulator/libLinqToObjectiveC.a(LinqToObjectiveC-dummy.o)
[ 9] /Users/Smyrl/Library/Developer/Xcode/DerivedData/TwitterInstant-ecppmzhbawtxkwctokwryodvgkur/Build/Products/Debug-iphonesimulator/libLinqToObjectiveC.a(NSArray+LinqExtensions.o)
[ 10] /Users/Smyrl/Library/Developer/Xcode/DerivedData/TwitterInstant-ecppmzhbawtxkwctokwryodvgkur/Build/Products/Debug-iphonesimulator/libLinqToObjectiveC.a(NSDictionary+LinqExtensions.o)
Первый столбец содержит перекрестные ссылки на таблицу символов, в которой я нуждаюсь, поэтому я могу найти их:
$ cat TwitterInstant-LinkMap-normal-x86_64.txt | grep -e "\[ 8\]"
который дает мне:
0x100087161 0x0000001B [ 8] literal string: PodsDummy_LinqToObjectiveC
0x1000920B8 0x00000008 [ 8] anon
0x100093658 0x00000048 [ 8] l_OBJC_METACLASS_RO_$_PodsDummy_LinqToObjectiveC
0x1000936A0 0x00000048 [ 8] l_OBJC_CLASS_RO_$_PodsDummy_LinqToObjectiveC
0x10009F0A8 0x00000028 [ 8] _OBJC_METACLASS_$_PodsDummy_LinqToObjectiveC
0x10009F0D0 0x00000028 [ 8] _OBJC_CLASS_$_PodsDummy_LinqToObjectiveC
Второй столбец содержит размер рассматриваемого символа (в шестнадцатеричном виде), поэтому, если я их добавлю, я получаю 0x103 или 259 байтов.
Даже лучше, я могу немного взломать поток, чтобы уничтожить его до основных элементов и сделать дополнение для меня:
$ cat TwitterInstant-LinkMap-normal-x86_64.txt | grep -e "\[ 8\]" | grep -e "0x" | awk '{print $2}' | xargs printf "%d\n" | paste -sd+ - | bc
который дает мне число прямо вверх:
259
Выполняя то же самое для "\[ 9\]"
(13016 bytes) и "\[ 10\]"
(5503 байта) и добавляя их к предыдущим 259 байтам, дает мне 18778 байт.
Вы, безусловно, можете улучшить хакерство потока, которое я сделал здесь, чтобы сделать его немного более надежным (в этой реализации вы должны убедиться, что вы правильно указали количество пробелов и скопировали скобки), но вы на наименьшая идея.