ในกรณีที่ไม่มีมาโครตัวประมวลผลล่วงหน้าจะมีวิธีการกำหนดแฟล็กจำเพาะของจริงที่เป็นประโยชน์ในระดับโปรเจ็กต์ในโปรเจ็กต์ Xcode


174

ก่อนสวิฟท์ฉันจะกำหนดชุดของชุดรูปแบบสำหรับอัลฟาเบต้าและการสร้างการกระจาย ชุดรูปแบบเหล่านี้แต่ละชุดจะมีมาโครที่กำหนดให้กับพฤติกรรมบางอย่างในระดับโครงการ ตัวอย่างที่ง่ายที่สุดคือแมโคร DEBUG = 1 ที่กำหนดโดยค่าเริ่มต้นสำหรับโครงการ Xcode ทั้งหมดในโครงร่างเริ่มต้นสำหรับการสร้างการเรียกใช้ สามารถสืบค้น #ifdef DEBUG ... และทำการตัดสินใจในรหัสได้แม้กระทั่งการรวบรวมรหัสที่ไม่จำเป็น

ดูเหมือนว่าการกำหนดค่าการกำหนดค่าชนิดนี้นั้นไม่ง่ายนักเมื่อใช้ swift เนื่องจากไม่รองรับมาโคร ใครช่วยแนะนำวิธีการที่ใกล้เคียงกันฉันไม่สนว่าโค้ดจะถูกคอมไพล์แล้วหรือยัง ฉันต้องการเกตคุณลักษณะตามรูปแบบบิลด์

คำตอบ:


468

ในสวิฟท์คุณยังสามารถใช้ "# ถ้า / # อื่น / # endif" preprocessor แมโคร (ถึงแม้จะมีข้อ จำกัด เพิ่มเติม) ตามเอกสารแอปเปิ้ล นี่คือตัวอย่าง:

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

ตอนนี้คุณต้องตั้งค่าสัญลักษณ์ "DEBUG" ที่อื่น ตั้งค่าในส่วน "Swift Compiler - Custom Flags" บรรทัด "Other Swift Flags" คุณเพิ่มสัญลักษณ์การดีบักด้วย-D DEBUGรายการ

(การตั้งค่า Build -> Swift Compiler - Custom Flags) ป้อนคำอธิบายรูปภาพที่นี่

ตามปกติคุณสามารถตั้งค่าที่แตกต่างกันเมื่ออยู่ใน Debug หรือเมื่ออยู่ใน Release

ฉันทดสอบด้วยโค้ดจริง ดูเหมือนจะไม่เป็นที่รู้จักในสนามเด็กเล่น


5
โปรดทราบว่าคุณสามารถใช้ #elseif บรรทัดเพื่อเพิ่มการทดสอบเพิ่มเติมได้ น่าสนใจพอคุณสามารถเข้าถึงคำจำกัดความได้ นั่นคือ define -DDEBUG = 5 (หรือ = "FOO") แล้วลองพิมพ์ด้วย "println (DEBUG คือ (DEBUG)" DEBUG) "บรรทัดนั้นไม่มีข้อผิดพลาด แต่ไม่ได้ทำอะไรเลย
เดวิดเอช

10
หมายเหตุ: "การตั้งค่าในตัว -> Swift Compiler -> Custom Flags" ไม่ปรากฏในการตั้งค่าการสร้าง "พื้นฐาน" ต้องแสดงการตั้งค่าการสร้าง "ทั้งหมด" เพื่อให้ปรากฏ
levibostian

7
@EugeneDubinin อาจเป็นเพราะคุณควรตรวจสอบให้แน่ใจว่า$(inherited)ใช้ในการตั้งค่าเป้าหมายเพื่อรับช่วงการตั้งค่าโครงการ
DanSkeel

2
@DanSkeel จับดีเพิ่ม$(inherited)ทำให้ความคิดเห็นของฉันไม่เกี่ยวข้องขอขอบคุณ!
Yevhen Dubinin

10
ใน Xcode 8 ขณะนี้ยังมีการตั้งค่า "เงื่อนไขการรวบรวมที่ใช้งานอยู่" ในส่วน "Swift Compiler - Custom Flags" คุณสามารถเพิ่มธงได้ที่นี่โดยไม่ต้องใช้ -D
Marcus

32

เราพบปัญหาที่ไม่ต้องการตั้งค่าสถานะคอมไพเลอร์แบบ swift เนื่องจากเราไม่ต้องการตั้งค่าและทำให้ทันสมัยสำหรับเป้าหมายที่แตกต่างกัน ฯลฯ นอกจากนี้ใน codebase แบบผสมของเราเราไม่ต้องการจดจำ เพื่อตั้งค่าสถานะของเราอย่างเหมาะสมตลอดเวลาสำหรับแต่ละภาษา

สำหรับเราเราได้ประกาศไฟล์ใน ObjC

PreProcessorMacros.h

extern BOOL const DEBUG_BUILD;

ใน. m

PreProcessorMacros.m

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

จากนั้นในวัตถุประสงค์ Bridging Header ของคุณ

#import "PreProcessorMacros.h"

ตอนนี้ใช้สิ่งนี้ใน codebase Swift ของคุณ

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

นี่เป็นวิธีแก้ปัญหาแน่นอน แต่แก้ไขปัญหาของเราได้ดังนั้นฉันโพสต์ไว้ที่นี่ด้วยความหวังว่าจะช่วยได้ มันไม่ได้มีไว้เพื่อแนะนำว่าคำตอบที่มีอยู่ไม่ถูกต้อง


11
จุดรวมของแมโครคือการเปลี่ยนรหัสตามการกำหนดค่าการสร้าง คุณกำลังนำ if หากกลับไปที่รันไทม์คุณไม่จำเป็นต้องมีแมโครสำหรับสิ่งนั้น
Berik

18
@Berik - ฉันโพสต์โซลูชันที่ถูกต้องด้วยความหวังว่ามันอาจช่วยให้ผู้อื่นพยายามแก้ไขปัญหานี้โดยเฉพาะในโครงการหลายภาษา หากปัญหาของคุณต้องไม่รวบรวมรหัสเฉพาะที่ดี นอกจากนี้ความคิดเห็นก็ดีโดยเฉพาะอย่างยิ่งเมื่อมันให้ความรู้บางอย่างว่าทำไมนี่อาจไม่ใช่ทางออกสำหรับพวกเขา รวมทั้งขอให้จดบันทึกในคำตอบเกี่ยวกับข้อ จำกัด ของวิธีการนี้ Downvoting นั้นไม่จำเป็นและไม่สนับสนุนทางเลือกอื่น ๆ ที่อาจเป็นประโยชน์ต่อผู้อื่นในการแก้ปัญหาที่คล้ายกัน นอกจากนี้ op ยังกล่าวว่า "ฉันไม่สนใจว่าจะรวบรวมรหัส" หรือไม่
โลแกน

5

โซลูชัน swifty เพิ่มเติมสำหรับวิธี Logans ตั้ง-D DEBUGในOther Swift FlagsของSwift Compiler - Custom Flagsส่วนในการสร้างการตั้งค่าเป้าหมายของคุณ

จากนั้นประกาศวิธีการดังต่อไปนี้ในขอบเขตทั่วโลก:

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

ตอนนี้ใช้มันเป็น

if isDebugMode {
    // Do debug stuff
}

1

สำหรับฉันให้ตั้งค่ารายการดีบั๊กของ " Active Compilation Condition " เป็น "DEBUG"

จากนั้นใช้งานคีย์ DEBGU ใน #IF DEBUG ทำงานในโหมดแก้ไขข้อบกพร่องและ #ELSE ในโหมดเผยแพร่:

  1. เลือกเป้าหมายของคุณ
  2. ในแท็บสร้างการตั้งค่าค้นหา "เงื่อนไขการรวบรวมที่ใช้งานอยู่"
  3. ตั้งค่าของรายการ "Debug" เป็น "YourKeyWord"
  4. ใช้ง่าย ๆ ดังนี้:

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

0

ฉันกำลังทำงานในฐานรหัสภาษาผสมที่รหัส obj-c ใช้แมโครเพื่อส่งข้อความการดีบักไปยังคอนโซล (และแมโครนั้นอาศัยการตั้งค่าสถานะตัวประมวลผลล่วงหน้า debug ของเรา) ฉันต้องการที่จะสามารถเรียกแมโครเดียวกันนั้นในรหัส swift ...

  1. ฉันสร้างวิธีการเรียนในหนึ่งในคลาส obj-c ของฉันที่เป็น wrapper รอบแมโครนั้น
  2. ฉันเพิ่มส่วนหัว obj-c ลงในไฟล์ส่วนหัวของบริดจ์
  3. ตอนนี้โค้ด swift ของฉันเรียกเมธอด class เป็น "proxy" ไปยังแมโคร obj-c

เป็นเรื่องน่ารำคาญเล็กน้อยที่ฉันไม่สามารถเรียกมาโครได้โดยตรงในรหัส swift แต่อย่างน้อยตอนนี้ฉันมีที่เดียวในโครงการเพื่อกังวลเกี่ยวกับการเปิด / ปิดการดีบัก

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.