Подтвердить что ты не робот

Как справиться с крупным проектом Swift?

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

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

    Command failed due to signal: Segmentation fault: 11

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

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

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

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

4b9b3361

Ответ 1

Swift toolchain все еще немного груб, вам нужно будет использовать временные временные решения, пока Apple не исправит это (см. ОБНОВЛЕНИЯ)

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

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

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

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

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

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

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

  • OUTDATED Попробуйте подход, описанный в этом блоге, он предполагает создание build script, который создает файл make. Он требует ручного вмешательства в сборку script (в ней содержится список быстрых файлов).

  • OUTDATED Попробуйте this взломать инкрементную технику компиляции

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

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

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

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

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

Конфигурация проекта (неправильная) (не относящаяся к Swift)

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

Ответ 2

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

Удалите все строки в Swift.

Эта тема SO имеет несколько хороших идей и это сообщение в блоге предложите

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

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

Ответ 3

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

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

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

Ответ 4

вы можете попробовать:

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

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

Ответ 5

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