swift - स्विफ्ट भाषा में#ifdef प्रतिस्थापन




xcode preprocessor (8)

एक्सकोड 8 और ऊपर

बिल्ड सेटिंग्स / स्विफ्ट कंपाइलर में कस्टम संकलन स्थितियों सेटिंग का उपयोग करें - कस्टम झंडे

  • स्विफ्ट कंपाइलर को सशर्त संकलन झंडे को पारित करने के लिए यह नई बिल्ड सेटिंग है।
  • सरल इस तरह झंडे जोड़ें: ALPHA , BETA आदि

फिर इसे संकलन की स्थिति के साथ जांचें:

#if ALPHA
    //
#elseif BETA
    //
#else
    //
#endif

युक्ति: आप #if !ALPHA आदि का भी उपयोग कर सकते हैं।

सी / सी ++ / उद्देश्य-सी में आप कंपाइलर प्रीप्रोसेसरों का उपयोग करके एक मैक्रो परिभाषित कर सकते हैं। इसके अलावा, आप संकलक प्रीप्रोसेसरों का उपयोग कर कोड के कुछ हिस्सों को शामिल / बहिष्कृत कर सकते हैं।

#ifdef DEBUG
    // Debug-only code
#endif

क्या स्विफ्ट में एक समान समाधान है?


सक्रिय संकलन स्थितियों के आधार पर isDebug Constant है

एक और, शायद सरल, समाधान जो अभी भी एक बुलियन में परिणाम देता है कि आप अपने कोडबेस में #if सशर्तियों को मिर्च किए बिना कार्यों में गुजर सकते हैं, DEBUG को आपके प्रोजेक्ट बिल्ड लक्ष्य की Active Compilation Conditions में से एक के रूप में परिभाषित करना है और निम्न में शामिल करना है (मैं इसे एक के रूप में परिभाषित करता हूं वैश्विक स्थिर):

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

कंपाइलर अनुकूलन सेटिंग्स के आधार पर isDebug Constant है

यह अवधारणा केनीट के जवाब पर बनाता है

दोनों की तुलना करते समय मुख्य लाभ यह है कि यह निजी या अनियंत्रित तरीकों पर निर्भर नहीं है।

स्विफ्ट 4 में :

let isDebug: Bool = {
    var isDebug = false
    // function with a side effect and Bool return value that we can pass into assert()
    func set(debug: Bool) -> Bool {
        isDebug = debug
        return isDebug
    }
    // assert:
    // "Condition is only evaluated in playgrounds and -Onone builds."
    // so isDebug is never changed to true in Release builds
    assert(set(debug: true))
    return isDebug
}()

प्रीप्रोसेसर मैक्रोज़ और केनिटम के उत्तर की तुलना में,

  • ✓ आपको इसका उपयोग करने के लिए एक कस्टम- -D DEBUG ध्वज को परिभाषित करने की आवश्यकता नहीं है
  • ~ यह वास्तव में अनुकूलन सेटिंग्स के संदर्भ में परिभाषित किया गया है, न कि एक्सकोड बिल्ड कॉन्फ़िगरेशन
  • दस्तावेज , जिसका अर्थ है कि फ़ंक्शन सामान्य API रिलीज़ / बहिष्करण पैटर्न का पालन करेगा।

  • ✓ यदि / अन्य में प्रयोग करना "निष्पादित नहीं किया जाएगा" चेतावनी उत्पन्न नहीं करेगा।


एक्सकोड 8 के लिए मेरे दो सेंट:

ए) -D उपसर्ग का उपयोग कर एक कस्टम ध्वज ठीक काम करता है, लेकिन ...

बी) सरल उपयोग:

एक्सकोड 8 में एक नया खंड है: डीबग और रिलीज के लिए पहले से ही दो पंक्तियों के साथ "सक्रिय संकलन शर्तें"।

बस बिना परिभाषित अपनी -D जोड़ें।


कई परिस्थितियों में, आपको वास्तव में सशर्त संकलन की आवश्यकता नहीं है; आपको केवल सशर्त व्यवहार की आवश्यकता है जिसे आप चालू और बंद कर सकते हैं। इसके लिए, आप एक पर्यावरण चर का उपयोग कर सकते हैं। इसका एक बड़ा फायदा है कि आपको वास्तव में पुन: संकलित नहीं करना है।

आप पर्यावरण चर सेट कर सकते हैं, और योजना संपादक में इसे आसानी से चालू या बंद कर सकते हैं:

आप NSProcessInfo के साथ पर्यावरण चर को पुनर्प्राप्त कर सकते हैं:

    let dic = NSProcessInfo.processInfo().environment
    if dic["TRIPLE"] != nil {
        // ... do secret stuff here ...
    }

यहां एक वास्तविक जीवन उदाहरण है। मेरा ऐप केवल डिवाइस पर चलता है, क्योंकि यह संगीत पुस्तकालय का उपयोग करता है, जो सिम्युलेटर पर मौजूद नहीं है। फिर, सिम्युलेटर पर उन डिवाइसों के लिए स्क्रीन शॉट्स लेने के लिए, जिनके पास मेरा स्वामित्व नहीं है? उन स्क्रीन शॉट्स के बिना, मैं ऐपस्टोर में सबमिट नहीं कर सकता।

मुझे नकली डेटा और इसे संसाधित करने का एक अलग तरीका चाहिए । मेरे पास दो पर्यावरण चर हैं: एक, जिस पर स्विच किया जाता है, ऐप को मेरे डिवाइस पर चलते समय वास्तविक डेटा से नकली डेटा उत्पन्न करने के लिए कहता है; दूसरा, जब स्विच किया जाता है, सिम्युलेटर पर चलते समय नकली डेटा (गायब संगीत पुस्तकालय नहीं) का उपयोग करता है। योजना संपादक में पर्यावरण परिवर्तनीय चेकबॉक्स के लिए उन विशेष मोडों को चालू / बंद करना आसान है। और बोनस यह है कि मैं अपने ऐप स्टोर बिल्ड में गलती से उनका उपयोग नहीं कर सकता, क्योंकि संग्रह में कोई पर्यावरण चर नहीं है।


जैसा कि ऐप्पल डॉक्स में बताया गया है

स्विफ्ट कंपाइलर में प्रीप्रोसेसर शामिल नहीं है। इसके बजाए, यह समान कार्यक्षमता को पूरा करने के लिए संकलन-समय विशेषताओं, कॉन्फ़िगरेशन और भाषा सुविधाओं का लाभ उठाता है। इस कारण से, प्रीप्रोसेसर निर्देश स्विफ्ट में आयात नहीं किए जाते हैं।

कस्टम बिल्ड कॉन्फ़िगरेशन का उपयोग करके मैं जो चाहता था उसे हासिल करने में कामयाब रहा हूं:

  1. अपने प्रोजेक्ट पर जाएं / कस्टम फ्लैग के लिए अपना लक्ष्य / बिल्ड सेटिंग्स / सर्च चुनें
  2. आपके चुने हुए लक्ष्य के लिए डीबग और रिलीज दोनों के लिए -D उपसर्ग (बिना सफेद रिक्त स्थान) का उपयोग करके अपना कस्टम ध्वज सेट करें
  3. आपके पास हर लक्ष्य के लिए ऊपर दिए गए कदम उठाएं

यहां बताया गया है कि आप लक्ष्य के लिए कैसे जांचते हैं:

#if BANANA
    print("We have a banana")
#elseif MELONA
    print("Melona")
#else
    print("Kiwi")
#endif

स्विफ्ट 2.2 का उपयोग करके परीक्षण किया गया


यह जॉन विलिस के जवाब पर बनाता है जो जोर देने पर निर्भर करता है, जो केवल डीबग संकलन में निष्पादित होता है:

func Log(_ str: String) { 
    assert(DebugLog(str)) 
}
func DebugLog(_ str: String) -> Bool { 
    print(str) 
    return true
}

मेरा उपयोग केस प्रिंट स्टेटमेंट लॉगिंग के लिए है। आईफोन एक्स पर रिलीज संस्करण के लिए यहां एक बेंचमार्क है:

let iterations = 100_000_000
let time1 = CFAbsoluteTimeGetCurrent()
for i in 0 ..< iterations {
    Log ("⧉ unarchiveArray:\(fileName) memoryTime:\(memoryTime) count:\(array.count)")
}
var time2 = CFAbsoluteTimeGetCurrent()
print ("Log: \(time2-time1)" )

प्रिंट:

Log: 0.0

ऐसा लगता है कि स्विफ्ट 4 पूरी तरह से फ़ंक्शन कॉल को समाप्त करता है।


हां तुम यह कर सकते हो।

स्विफ्ट में आप अभी भी "# if / # else / # endif" प्रीप्रोसेसर मैक्रोज़ (हालांकि अधिक बाधित) का उपयोग कर सकते हैं, ऐप्पल दस्तावेज़ों के अनुसार। यहां एक उदाहरण दिया गया है:

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

अब, आपको कहीं और "DEBUG" प्रतीक सेट करना होगा, हालांकि। इसे "स्विफ्ट कंपाइलर - कस्टम फ्लैग" अनुभाग, "अन्य स्विफ्ट ध्वज" पंक्ति में सेट करें। आप -D DEBUG एंट्री के साथ DEBUG प्रतीक जोड़ते हैं।

सामान्य रूप से, जब आप डीबग में या रिलीज़ में होते हैं तो आप एक अलग मूल्य निर्धारित कर सकते हैं।

मैंने इसे वास्तविक कोड में परीक्षण किया और यह काम करता है; हालांकि यह एक खेल के मैदान में मान्यता प्राप्त प्रतीत नहीं होता है।

आप here मेरी मूल पोस्ट पढ़ सकते हैं।

महत्वपूर्ण नोट: -DDEBUG=1 काम नहीं करता है। केवल- -D DEBUG काम करता है। लगता है कि संकलक एक विशिष्ट मूल्य के साथ ध्वज को अनदेखा कर रहा है।








preprocessor-directive