Xcode 11 mengkompilasi ulang (hampir?) Seluruh proyek saya, bahkan jika saya hanya mengubah variabel pribadi lokal, atau mengubah nilai konstanta dalam lingkup lokal, kadang-kadang bahkan dalam lingkup fungsi pribadi lokal. Saya kadang-kadang bisa mendapatkan 2 atau 3 perubahan dengan build cepat seperti yang diharapkan, tetapi segera memutuskan untuk mengkompilasi ulang semuanya lagi (yang terlalu lama).
Ada ide apa yang mungkin terjadi? Apakah Xcode tidak dapat menentukan apa yang berubah, mengapa ia mengkompilasi ulang banyak hal lain (bahkan modul lain).
Setiap saran sangat dihargai, terima kasih!
Jawaban:
Kami memiliki masalah yang sama dan kami memperbaikinya. Dua kali.
Bangun tambahan (mesin bangun yang sama):
sebelum: ~ 10m setelah: ~ 35s
BAGAIMANA?
Mari kita mulai dengan pengalaman kita terlebih dahulu. Kami memiliki proyek Swift / Obj-C yang besar dan itulah yang menjadi perhatian utama: waktu pembangunan lambat dan Anda harus membuat proyek baru untuk mengimplementasikan fitur baru (secara harfiah). Poin bonus untuk penyorotan sintaks yang tidak berfungsi.
Teori
Untuk benar-benar memperbaiki ini, Anda harus benar - benar memahami cara kerja sistem build. Misalnya, mari coba cuplikan kode ini:
dan bayangkan Anda menggunakan semua impor ini dalam file Anda. Dan juga file ini tergantung pada file lain, yang tergantung pada perpustakaan lain, yang pada gilirannya menggunakan perpustakaan lain dll.
Jadi untuk mengkompilasi file Anda Xcode harus mengkompilasi setiap perpustakaan yang Anda sebutkan dan setiap file tergantung, jadi jika Anda mengubah salah satu dari file "inti" Xcode harus membangun kembali seluruh proyek secara harfiah.
Build Xcode multi-threaded , tetapi terdiri dari banyak pohon single-threaded .
Jadi pada langkah pertama setiap build tambahan Xcode menentukan file mana yang harus dikompilasi ulang dan membangun pohon AST . Jika Anda mengubah file yang bertindak sebagai " dapat diandalkan " pada file lain, maka setiap file lain yang bertindak sebagai " tergantung " harus dikompilasi ulang.
Jadi saran pertama adalah untuk menurunkan kopling . Bagian-bagian proyek Anda harus independen satu sama lain.
Obj-C / Swift bridge
Masalah dengan pohon-pohon itu jika Anda menggunakan jembatan Obj-C / Swift, Xcode harus melalui fase lebih dari biasanya:
Dunia yang sempurna:
Obj-C / Swift bridge:
Jadi, jika Anda mengubah sesuatu dari langkah 1 atau 2, pada dasarnya Anda dalam masalah. Solusi terbaik adalah meminimalkan Obj-C / Swift Bridge (dan menghapusnya dari proyek Anda).
Jika Anda tidak memiliki Obj-C / Swift Bridge, itu luar biasa dan Anda bisa melanjutkan ke langkah berikutnya:
Manajer Paket Swift
Saatnya pindah ke SwiftPM (atau setidaknya mengkonfigurasi Cocoapod Anda lebih baik).
Masalahnya, sebagian besar kerangka kerja dengan konfigurasi Cocoapods standar menyeret banyak hal yang tidak Anda butuhkan.
Untuk menguji ini buat proyek kosong dengan hanya satu ketergantungan seperti PinLayout, misalnya dan coba tulis kode ini dengan Cocoapods (konfigurasi default) dan SwiftPM.
Spoiler: Cocoapods akan mengkompilasi kode ini, karena Cocoapods akan mengimpor SETIAP IMPOR PinLayout (termasuk UIKit) dan SwiftPM tidak akan melakukannya karena SwiftPM mengimpor kerangka kerja secara atom.
Retas kotor
Apakah Anda ingat Xcode build multi-threaded?
Nah, Anda dapat menyalahgunakannya, jika Anda dapat membagi proyek Anda menjadi banyak bagian independen dan mengimpor semuanya sebagai kerangka kerja independen ke proyek Anda. Itu memang menurunkan kopling dan itu sebenarnya solusi pertama yang kami gunakan, tapi itu sebenarnya tidak terlalu efektif, karena kami hanya bisa mengurangi waktu build tambahan menjadi ~ 4-5m yang TIDAK ADA dibandingkan dengan metode pertama.
sumber
Tidak ada peluru emas di sini, tetapi banyak hal yang perlu diperiksa:
Pastikan Anda benar-benar menggunakan konfigurasi Debug dalam skema Anda
Lihat di bawah untuk cara memastikan Anda menggunakan build tambahan versus seluruh modul per saran. Pastikan juga Tingkat Pengoptimalan untuk Debug Anda tidak ada.
Jika Anda menggunakan kerangka berat tipe-inferensi seperti RxSwift, menambahkan anotasi tipe eksplisit dapat mempercepat waktu pembuatan.
Jika proyek ini sangat besar, Anda dapat mempertimbangkan refactoring keluar grup logis file sumber ke dalam kerangka kerja, tetapi itu mungkin terlalu drastis dari perubahan daripada yang Anda inginkan
Mungkin membantu jika Anda memberikan beberapa lebih spesifik tentang proyek: apakah Anda secara statis menghubungkan perpustakaan apa pun? Apakah itu kerangka kerja atau target aplikasi? Seberapa besar dan versi cepat apa yang Anda gunakan? Apakah Anda memiliki Fase Bangun kustom seperti linter atau pembuatan kode yang kadang-kadang dapat dilewati?
sumber