Как справиться с большим проектом Swift?


после iPhone приложение, которое я пишу в Swift, становится довольно большим (>150 .swift files + различные Objective-C libs), Xcode start ведут себя довольно плохо:

  • каждую вторую компиляцию я получаю различные ошибки, например:

    Command failed due to signal: Segmentation fault: 11

  • компиляция занимает огромное количество времени (>2 мин на MacBook Pro Retina)
  • и так далее.

мне просто интересно, если все же проблемы и, возможно, кто-то нашел способ уменьшить этот кошмар?

что я сделал до сих пор-я разделил проект на несколько динамических фреймворков, которые я связываю с основным проектом, это помогает сократить время компиляции, но ввести некоторые новые проблемы.

Я также использую iRamDisk, чтобы сохранить DerivedData папка в оперативной памяти и периодически удалять все файлы из него, это иногда помогает с sourcekit аварий.

5 53

5 ответов:

Swift toolchain все еще немного грубый, вам нужно будет использовать некоторые временные обходные пути, пока Apple не исправит его (см. обновления ниже)

вот список предметов, которые вы можете сделать, чтобы не сойти с ума.

медлительность, вызванная незрелым компилятором Swift

  • измените рабочий процесс разработки с помощью инъекция для Xcode. После того как вы установили плагин, вы сможете вводить изменения в коде симулятор\устройство без перекомпиляции. Вам не нужно жестко кодировать\изменять что-либо в вашем проекте. Мы начали использовать его недавно на работе, и это оказало огромное влияние на нашу сторону, даже если это не относится к каждому случаю использования (например, вы не можете создавать новые функции, вы можете только изменять существующие).

  • некоторые конкретные конструкции кода, которые компилятор не любит и занимает слишком много времени для компиляции. Наиболее распространенная проблема связана с проверкой типа это замедляет время компиляции экспоненциально в зависимости от того, сколько проверок типа ему нужно сделать (Подробнее здесь для практических примеров и здесь для подробного объяснения). Для того, чтобы определить, если вы страдаете от этой проблемы, вы можете следовать этому блоге, вы будете собирать информацию о функциях, которые создают медлительность, используя некоторые дополнительные флаги компилятора. В качестве альтернативы вы можете использовать этот плагин для Xcode для определения источник медлительности сборки.

  • используйте динамические рамки с умом, где это имеет смысл. Перекомпиляция фреймворка будет выполнена только при изменении одного из его файлов Swift (динамические фреймворки доступны только для iOS >= 7).

  • сконденсировать код в тех же файлах. Уменьшение количества файлов Swift значительно ускоряет процесс компиляции. Вы можете легко достичь этого, включив "оптимизацию всего модуля", добавив пользовательский пользовательский флаг SWIFT_WHOLE_MODULE_OPTIMIZATION и установите его в YES и в то же время установите уровень оптимизации в none (чтобы отключить оптимизацию, которая сделает его медленным) устаревшийвы можете рассмотреть возможность использования этого суть, это скрипт сборки, который сворачивает весь ваш код в " слияние.Свифт файл". Вам нужно будет создать новую цель для него, но это стоит пытаться.

  • дважды проверьте, что указано здесь (там есть еще несколько причин misc, потому что компиляция медленная)

  • устаревшийпопробуйте подход, описанный в этом блоге, он включает в себя создание сценария сборки, который генерирует make-файл. Это требует ручного вмешательства в сценарий сборки (он содержит список файлов SWIFT).

  • устаревший попробовать этой взламывается инкрементная компиляция техника

обновление: инкрементные сборки введены на Swift 1.2 (Xcode 6.3)

Apple, наконец, представила инкрементные сборки с Swift 1.2 (поставляется с Xcode 6.3). Это не все еще идеально, но это огромное улучшение.

отныне класс перекомпилируется только при его изменении (или при изменении одного из классов, от которого он зависит). Однако компилятор все еще не может понять, являются ли изменения в классе к его интерфейсу или нет. Поэтому любое изменение класса вызывает перекомпиляцию этого класса и всех его зависимостей.

обновление: Перекомпилируйте зависимые классы только при изменении открытого интерфейса, введенного в Swift 2.1 (Xcode 7.1)

начиная с Swift 2.1 (Xcode 7.1), зависимые классы перекомпилируются только при изменении открытого интерфейса класса, а не при каждом изменении. Это имеет огромное значение, в частности, для больших проекты.

конфигурация проекта (mis) (не связанная с Swift)

  • убедитесь, что" построить только активную архитектуру " да для отладки.
  • убедитесь, что вы не добавили сценарии компиляции pre\post, которые занимают слишком много времени.

У Apple есть несколько советов для ускорения сборки Xcode в Техническое Примечание 2190. Вы думали о создание и предварительная компиляция собственной структуры для аутсорсинга неизменных Swift модулей или некоторых / всех Objective-C кода?

удалить все выводы типа в Swift.

это так тема есть некоторые хорошие идеи и это блоге предлагаю

  1. остановить генерацию пакетов dSYM и
  2. избежать компиляции с -O4 при использовании Clang.

хотя многие из этих улучшений связаны с Objective-C, я совершенно уверен, что некоторые из них по-прежнему актуальны для Swift.

компиляция (re) - это известная проблема, которая, я уверен, будет решена в ближайшее время. Некоторые рекомендации:

  • используйте Objective C, где это возможно-он быстро компилируется, даже если он является частью проекта Swift
  • разделить код на основ
  • указать типы вместо того, чтобы оставить его до компилятора, чтобы вывести их

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

вы могли бы попробовать:

  • обновление объема оперативной памяти на вашем компьютере
  • Если у вас есть несколько .быстрые файлы, которые делают что-то на одном контроллере представления, попробуйте сжать их в один .swift файл на контроллер вида
  • настройка параметров в разделе Источники компиляции, чтобы увидеть, если у вас есть какие-либо дубликаты или если есть какие-либо сценарии или настройки, которые можно добавить, чтобы сделать его компиляцию быстрее...

вы также можете взглянуть на этой ответы post для некоторых подсказок о том, что вы можете сделать, чтобы замедлить время компиляции

Я обнаружил, что одной из основных причин ошибок сегментации и медленной компиляции является жесткое кодирование больших массивов и словарей, особенно при объявлении их глобальными константами и попытке доступа к значениям из них изнутри другого .быстрый файл. Когда я храню все эти данные внутри plists, эти проблемы исчезли.