web-dev-qa-db-ja.com

大きいSwift Project?

私が書いているiPhoneアプリの後、Swift=非常に大きくなります(> 150個の.Swiftファイル+さまざまなObjective-Cライブラリ))、Xcodeの起動はかなりひどく動作します:

  • コンパイルのたびに、さまざまなエラーが発生します。例:

    Command failed due to signal: Segmentation fault: 11

  • コンパイルには膨大な時間がかかります(MacBook Pro Retinaでは2分以上)
  • 等々。

誰もが同じ問題を抱えており、おそらく誰かがこの悪夢を減らす方法を見つけたのだろうか?

これまでに行ったこと-プロジェクトをメインプロジェクトからリンクする複数の動的フレームワークに分割します。これにより、コンパイル時間が短縮されますが、いくつかの新しい問題が発生します。

また、iRamDiskを使用してDerivedDataフォルダーをRAMに保持し、そこからすべてのファイルを定期的に削除します。SourceKitがクラッシュする場合があります。

53

Swiftツールチェーンはまだ少し粗末です。Apple修正するまで一時的な回避策を使用する必要があります([〜#〜] updates [〜# 〜]以下)

以下は、気が狂わないようにするためにできる項目のリストです。

未熟Swiftコンパイラーによるスローダウン

  • Injection for Xcode を使用して開発ワークフローを変更します。プラグインをインストールすると、シミュレーターのデバイスにコードの変更を挿入できます再コンパイルなしで。プロジェクトで何かをハードコードしたり変更したりする必要はありません。私たちは最近仕事でそれを使い始め、すべてのユースケースに適用されない場合でも、私たちの側に大きな影響を与えました(たとえば、新しい関数を作成することはできず、既存の関数のみを変更することができます)。

  • コンパイラが気に入らず、コンパイルに時間がかかりすぎる特定のコード構成。最も一般的な問題は、実行する必要がある型チェックの数に基づいて、コンパイル時間を指数関数的に遅くする型チェッカーにあります(詳細は here の例と here の詳細な説明)。この問題に苦しんでいるかどうかを識別するために、この ブログ投稿 をたどることができます。コンパイラーの追加フラグを使用して、スローを引き起こす関数に関する情報を収集します。または、この Xcodeプラグイン を使用して、ビルドの遅延の原因を特定できます。

  • 動的なフレームワークを適切に使用してください。フレームワークの再コンパイルは、そのSwiftファイル(動的フレームワークはiOS> = 7でのみ使用可能)のいずれかを変更した場合にのみ行われます。

  • 同じファイル内の圧縮コード。 Swiftファイルの数を減らすと、コンパイルプロセスが大幅に高速化されます。ユーザー定義のカスタムフラグSwift_WHOLE_MODULE_OPTIMIZATIONそしてYESに設定すると同時に最適化レベルをnoneに設定します(遅くなる最適化を無効にするため)[〜#〜] outdated [〜#〜] これを使用することを検討することもできます Gist 、これは「merge.Swift」ファイル内のすべてのコードを折りたたむビルドスクリプトです。新しいターゲットを作成する必要がありますが、試してみる価値はあります。

  • リストされていることを再確認してください here (コンパイルが遅いため、いくつかのその他の理由があります)

  • [〜#〜] outdated [〜#〜] この ブログ投稿 で説明されているアプローチを試してください。メイクファイルを生成するビルドスクリプトを作成する必要があります。ビルドスクリプトの手動操作が必要です(Swiftファイルのリストが含まれています)。

  • [〜#〜] outdated [〜#〜] this インクリメンタルコンパイルテクニックをハックした

UPDATE:Swift 1.2(Xcode 6.3)で導入されたインクリメンタルビルド

AppleはついにSwift 1.2(Xcode 6.3に同梱))のインクリメンタルビルドを導入しました。まだ完璧ではありませんが、それは大きな改善です。

これ以降、クラスは変更されたとき(または依存しているクラスの1つが変更されたとき)にのみ再コンパイルされます。ただし、クラスへの変更がそのインターフェイスに対するものかどうかは、コンパイラーにはまだ理解できません。したがって、クラスに何らかの変更を加えると、そのクラスとそのすべての依存関係が再コンパイルされます。

UPDATE:Swift 2.1(Xcode 7.1))で導入されたパブリックインターフェイスの変更時にのみ依存クラスを再コンパイルします

Swift 2.1(Xcode 7.1)から始まり、依存クラスは、クラスのパブリックインターフェイスを変更するときにのみ再コンパイルされ、すべての変更ではありません。これは、特に大きなプロジェクトで大きな違いを生じます。

プロジェクト(mis)構成(Swiftに関連しない)

  • 「アクティブアーキテクチャのみをビルド」がデバッグ用にYESであることを確認してください。
  • 時間がかかりすぎるコンパイル前スクリプトとコンパイル後スクリプトを追加していないことを確認してください。
58
Daniele

(再)コンパイルは既知の問題であり、まもなく解決されると確信しています。いくつかの推奨事項:

  • 可能な場合はObjective Cを使用します-Swiftプロジェクトの一部であっても高速にコンパイルします
  • コードをフレームワークに分割する
  • 型をコンパイラに任せて推論するのではなく、型を指定する

繰り返しますが、これはすぐに修正される可能性が高いので、この時点でコードの書き換えや再編成に多額の投資をしないことが最善です。

2
MirekE

Appleは Technical Note 219 でXcodeビルドを高速化するためのアドバイスをいくつか持っています。 独自のフレームワークを作成してプリコンパイルする を変更せずにアウトソーシングする場合SwiftモジュールまたはObjective-Cコードの一部またはすべて)?

Swiftですべての型推論を削除します。

このSOトピック にはすてきなアイデアがあり、これ ブログ投稿 に提案する

  1. dSYMバンドルの生成を停止し、
  2. clangを使用している場合は、-O4でコンパイルしないでください。

これらの改善の多くはObjective-Cに関連していますが、それらのいくつかはまだSwiftに関連していると確信しています。

2
Michael Dorner

セグメンテーション違反とコンパイルの遅延の主な原因の1つは、特にそれらをグローバル定数として宣言し、別の.Swiftファイル内からそれらの値にアクセスしようとすると、大きな配列と辞書をハードコーディングすることです。すべてのデータをリストに保存すると、これらの問題はなくなります。

1
bzz

あなたが試すことができます:

  • コンピューターのRAMの量をアップグレードする
  • 同じView Controllerで処理を行う複数の.Swiftファイルがある場合は、それらをView Controllerごとに1つの.Swiftファイルに圧縮してみてください
  • コンパイルソースの下で設定を調整して、重複があるかどうか、またはコンパイルを高速化するために追加できるスクリプトや設定があるかどうかを確認します...

コンパイル時間を遅くするために何ができるかについてのヒントについては、 this 投稿の回答をご覧ください。

1
MoralCode