Önişlemci makrolarının yokluğunda, Xcode projesinde proje düzeyinde pratik şemaya özgü bayrakları tanımlamanın bir yolu var mı?


174

Hızlıdan önce alfa, beta ve dağıtım yapıları için bir dizi şema tanımlarım. Bu şemaların her biri, proje düzeyinde belirli davranışları kapatmak için tanımlanmış bir dizi makroya sahip olacaktır. Bunun en basit örneği, Run derlemesi için varsayılan şemadaki tüm Xcode projeleri için varsayılan olarak tanımlanan DEBUG = 1 makrosudur. Birisi #ifdef DEBUG ... sorgulamak ve buna göre kodu, hatta gerekli olmayan kod derleme olabilir.

Bu tür konfigürasyonlu geçitlerin, makrolar desteklenmediği için hızlı kullanımı kolay değildir. Birisi karşılaştırılabilir bir yaklaşım önerebilir miyim, kod derlenmiş olup olmadığını umursamıyorum, per se. Yine de, inşa şemasına dayalı özellikler kapısı istiyorum.

Yanıtlar:


468

Swift'te, Apple belgelerine göre "# if / # else / # endif" önişlemci makrolarını (daha kısıtlanmış olsa da) kullanabilirsiniz . İşte bir örnek:

#if DEBUG
    let a = 2
#else
    let a = 3
#endif

Şimdi, "DEBUG" sembolünü başka bir yerde ayarlamanız gerekir. "Swift Derleyici - Özel Bayraklar" bölümünde, "Diğer Swift Bayrakları" satırına ayarlayın. DEBUG sembolünü-D DEBUG giriş .

(Derleme Ayarları -> Swift Derleyici - Özel Bayraklar) resim açıklamasını buraya girin

Her zamanki gibi, Hata Ayıklama'da veya Yayındayken farklı bir değer ayarlayabilirsiniz.

Ben gerçek kod test; bir oyun alanında tanınmış gibi görünmüyor.


5
Daha fazla test eklemek için #elseif satırlarını da kullanabileceğinizi unutmayın. İlginç bir şekilde, tanıma erişebilir ancak ondan hiçbir şey çıkartamazsınız; yani, -DDEBUG = 5 (veya = "FOO") tanımlayın ve sonra "println (DEBUG is (DEBUG)") ile yazdırmayı deneyin. Bu satır hata oluşturmaz, ancak hiçbir şey yapmaz.
David H

10
Not: "Temel Ayarlar -> Swift Derleyici -> Özel Bayraklar" "Temel" oluşturma ayarlarında görünmez. Görünmesi için "Tümü" oluşturma ayarlarını göstermelidir.
levibostian

7
@EugeneDubinin muhtemelen $(inherited)proje ayarlarını devralmak için hedef ayarlarında kullanıldığından emin olmalısınız .
DanSkeel

2
@DanSkeel güzel yakalamak, ekleme yorumumu $(inherited)ilgisiz yapar, teşekkür ederim!
Yevhen Dubinin

10
Xcode 8'de artık "Swift Derleyici - Özel Bayraklar" bölümünde "Etkin Derleme Koşulları" ayarı da bulunmaktadır. Burada -D'ye ihtiyaç duymadan bayraklar ekleyebilirsiniz
Marcus

32

Hızlı derleyici bayraklarını ayarlamak istememekle ilgili bir sorunla karşılaştık, çünkü onları ayarlamak ve farklı hedefler için güncel tutmak istemedik. Ayrıca, karma kod tabanımızda hatırlamak istemedik bayraklarımızı her dil için uygun şekilde ayarlamak için.

Bizim için ObjC'de bir dosya beyan ettik

PreProcessorMacros.h

extern BOOL const DEBUG_BUILD;

.M içinde

PreProcessorMacros.m

#ifdef DEBUG
    BOOL const DEBUG_BUILD = YES;
#else
    BOOL const DEBUG_BUILD = NO;
#endif

Ardından, Objective-C Köprüleme Başlığınızda

#import "PreProcessorMacros.h"

Şimdi bunu Swift kod tabanınızda kullanın

if DEBUG_BUILD {
    println("debug")
} else {
    println("release")
}

Bu kesinlikle bir çözüm, ama sorunumuzu çözdü, bu yüzden burada yardımcı olacağını umarak gönderdim. Mevcut cevapların geçersiz olduğu anlamına gelmez.


11
Makronun tüm amacı kodu yapı yapılandırmasına göre değiştirmektir. Eğer if'i çalışma zamanına geri getiriyorsunuz, bunun için makroya ihtiyacınız yok.
Berik

18
@Berik - Özellikle çok dilli projelerde, bu sorunun bir yönünü çözmeye çalışan başkalarına da yardımcı olabileceği umuduyla geçerli bir çözüm yayınladım. Sorununuz iyi bir kod derleme gerektirmiyorsa. Ayrıca bir yorum, özellikle de bunun neden onlar için çözüm olmayabileceğini öğrendiğinde iyidir. Ayrıca bu yaklaşımın sınırlamaları hakkında cevapta bir not almayı istemek. Aşağı oylama gereksizdir ve benzer sorunları çözen başkalarına yardımcı olabilecek alternatif çözümleri cesaretlendirmez. Ayrıca, op "Kod derlenmiş olup olmadığını umurumda değil" diyor.
Logan

5

Logans yöntemine daha hızlı çözüm. Ayarlamak-D DEBUG içinde Other Swift Flagsbir Swift Compiler - Custom Flagshedefinizin inşa ayarlarında bölüm.

Ardından, küresel kapsamda aşağıdaki yöntemi bildirin:

#if DEBUG
let isDebugMode = true
#else
let isDebugMode = false
#endif

Şimdi onu

if isDebugMode {
    // Do debug stuff
}

1

Benim için " Etkin Derleme Koşulu " hata ayıklama öğesi "DEBUG" çalıştı olarak ayarlayın.

Daha sonra #IF DEBGU anahtar çalışmasını kullanarak DEBUG hata ayıklama modunda ve #ELSE sürüm modunda çalışır:

  1. Hedefinizi seçin,
  2. Yapı Ayarı sekmesinde "Etkin Derleme Koşulu" aramasını yapın,
  3. "Hata Ayıkla" öğesinin değerini "YourKeyWord" olarak ayarlayın,
  4. Aşağıdaki gibi basitçe kullanın:

    #if DEBUG
        print("You'r running in DEBUG mode!")
    #else
        print("You'r running in RELEASE mode!")
    #endif

0

Burada obj-c kodu hata ayıklama iletileri konsola göndermek için bir makro kullanır ve bu makro bizim hata ayıklayıcı önişlemci bayrağına dayalı bir karma dil kodu tabanı üzerinde çalışıyorum. Aynı makroyu hızlı kodda çağırabilmek istedim ...

  1. Bu makro etrafında bir sarıcı olan obj-c sınıflarımdan birinde bir sınıf yöntemi oluşturdum.
  2. Bu obj-c başlığını köprü başlık dosyamıza ekledim.
  3. Şimdi hızlı kodum bu sınıf yöntemini obj-c makrosuna "proxy" olarak çağırıyor.

Makroyu hızlı kodda doğrudan çağıramadığım için biraz can sıkıcı, ama en azından şimdi projede hata ayıklama bayrağımı açıp kapama konusunda endişelenecek tek bir yerim var.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.