Trong trường hợp không có macro tiền xử lý, có một cách để xác định các cờ cụ thể của lược đồ thực tế ở cấp dự án trong dự án Xcode


174

Trước khi nhanh chóng, tôi sẽ định nghĩa một tập hợp các lược đồ cho các bản dựng alpha, beta và phân phối. Mỗi lược đồ này sẽ có một tập hợp các macro được xác định để chuyển các hành vi nhất định ở cấp độ dự án. Ví dụ đơn giản nhất là macro DEBUG = 1 được xác định theo mặc định cho tất cả các dự án Xcode trong sơ đồ mặc định cho bản dựng Run. Người ta có thể truy vấn #ifdef DEBUG ... và đưa ra quyết định trong mã phù hợp, thậm chí biên dịch mã không cần thiết.

Có vẻ như loại gating cấu hình này không dễ sử dụng swift, vì macro không được hỗ trợ. Ai đó có thể đề xuất một cách tiếp cận tương đương không, tôi không quan tâm nếu mã được biên dịch, mỗi lần. Tôi muốn cổng tính năng dựa trên sơ đồ xây dựng, mặc dù.

Câu trả lời:


468

Trong Swift, bạn vẫn có thể sử dụng các macro tiền xử lý "# if / # other / # endif" (mặc dù bị ràng buộc nhiều hơn), theo tài liệu của Apple . Đây là một ví dụ:

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

Bây giờ, bạn phải đặt biểu tượng "DEBUG" ở nơi khác. Đặt nó trong phần "Trình biên dịch Swift - Cờ tùy chỉnh", dòng "Cờ Swift khác". Bạn thêm biểu tượng DEBUG với -D DEBUGmục nhập.

(Cài đặt bản dựng -> Trình biên dịch Swift - Cờ tùy chỉnh) nhập mô tả hình ảnh ở đây

Như thường lệ, bạn có thể đặt một giá trị khác khi ở chế độ Gỡ lỗi hoặc khi phát hành.

Tôi đã thử nó trong mã thực; nó dường như không được công nhận trong một sân chơi.


5
Lưu ý rằng bạn cũng có thể sử dụng các dòng #elseif để thêm các bài kiểm tra khác. Thật thú vị, bạn có thể truy cập định nghĩa nhưng không trích xuất được gì từ nó; nghĩa là, xác định -DDEBUG = 5 (hoặc = "FOO"), sau đó thử in nó bằng "println (DEBUG là (DEBUG)". Dòng đó không tạo ra lỗi, nhưng không làm gì cả.
David H

10
Lưu ý: "Cài đặt được xây dựng -> Trình biên dịch Swift -> Cờ tùy chỉnh" không hiển thị trong cài đặt bản dựng "Cơ bản". Phải hiển thị cài đặt bản dựng "Tất cả" để nó xuất hiện.
levibostian

7
@EugeneDubinin có lẽ vì bạn nên đảm bảo rằng nó $(inherited)được sử dụng trong cài đặt đích để kế thừa cài đặt dự án.
DanSkeel

2
@DanSkeel bắt tốt, thêm $(inherited)làm cho nhận xét của tôi không liên quan, cảm ơn bạn!
Yevhen Dubinin

10
Trong Xcode 8 giờ đây cũng có cài đặt "Điều kiện biên dịch hoạt động" trong phần "Trình biên dịch Swift - Cờ tùy chỉnh". Bạn có thể thêm cờ ở đây mà không cần -D
Marcus

32

Chúng tôi gặp phải một vấn đề là không muốn đặt cờ trình biên dịch nhanh vì chúng tôi không muốn phải đặt chúng và cập nhật chúng cho các mục tiêu khác nhau, v.v. Ngoài ra, trong cơ sở mã hỗn hợp của chúng tôi, chúng tôi không muốn ghi nhớ để đặt cờ của chúng tôi một cách thích hợp mọi lúc cho mỗi ngôn ngữ.

Đối với chúng tôi, chúng tôi đã khai báo một tệp trong ObjC

PreProcessorMacros.h

extern BOOL const DEBUG_BUILD;

Trong chúng

PreProcessorMacros.m

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

Sau đó, trong Tiêu đề Cầu nối Mục tiêu-C của bạn

#import "PreProcessorMacros.h"

Bây giờ, sử dụng điều này trong cơ sở mã Swift của bạn

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

Đây chắc chắn là một cách giải quyết, nhưng nó đã giải quyết được vấn đề của chúng tôi nên tôi đã đăng nó lên đây với hy vọng nó sẽ giúp ích. Nó không có nghĩa là đề nghị rằng các câu trả lời hiện có là không hợp lệ.


11
Toàn bộ quan điểm của macro là thay đổi mã dựa trên cấu hình bản dựng. Bạn đang mang if trở lại thời gian chạy, bạn không cần macro cho điều đó.
Berik

18
@Berik - Tôi đã đăng một giải pháp hợp lệ với hy vọng nó cũng có thể giúp những người khác cố gắng giải quyết một khía cạnh của vấn đề này, đặc biệt là trong các dự án đa ngôn ngữ. Nếu vấn đề của bạn yêu cầu không biên dịch mã cụ thể thì tốt. Ngoài ra một nhận xét là tốt, đặc biệt là khi nó giáo dục một số lý do tại sao điều này có thể không phải là giải pháp cho họ. Cũng yêu cầu ghi chú trong câu trả lời về những hạn chế của phương pháp này. Downvote là không cần thiết và không khuyến khích các giải pháp thay thế có thể hữu ích cho những người khác giải quyết các vấn đề tương tự. Ngoài ra, op nói "Tôi không quan tâm nếu mã được biên dịch".
Logan

5

Giải pháp tiện lợi hơn cho phương pháp Logans. Đặt -D DEBUGtrong Other Swift Flagscác Swift Compiler - Custom Flagsphần trong xây dựng thiết lập của mục tiêu của bạn.

Sau đó khai báo phương thức sau trong phạm vi toàn cầu:

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

Bây giờ sử dụng nó như là

if isDebugMode {
    // Do debug stuff
}

1

Đối với tôi, đặt mục gỡ lỗi của " Điều kiện biên dịch hoạt động " thành "DEBUG" hoạt động.

Sau đó, sử dụng khóa DEBGU hoạt động trong #IF DEBUG hoạt động ở chế độ gỡ lỗi và #ELSE ở chế độ phát hành:

  1. Chọn mục tiêu của bạn,
  2. Trong tab Cài đặt xây dựng tìm kiếm cho "Điều kiện biên dịch hoạt động",
  3. Đặt giá trị của mục "Gỡ lỗi" thành "YourKeyWord",
  4. Sử dụng đơn giản như sau:

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

0

Tôi đang làm việc trong một cơ sở mã ngôn ngữ hỗn hợp trong đó mã obj-c sử dụng macro để gửi thông báo gỡ lỗi đến bàn điều khiển (và macro đó phụ thuộc vào cờ tiền xử lý gỡ lỗi của chúng tôi). Tôi muốn có thể gọi cùng một macro trong mã nhanh chóng ...

  1. Tôi đã tạo một phương thức lớp trên một trong các lớp obj-c của tôi, đó là một trình bao bọc xung quanh macro đó.
  2. Tôi đã thêm tiêu đề obj-c vào tệp tiêu đề cầu của chúng tôi.
  3. Bây giờ mã swift của tôi gọi phương thức lớp đó là "proxy" cho macro obj-c.

Thật khó chịu khi tôi không thể gọi macro ngay lập tức trong mã nhanh chóng, nhưng ít nhất bây giờ tôi chỉ có một vị trí trong dự án để lo lắng về việc bật / tắt cờ gỡ lỗi.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.