2013-10-01 11 views
6

Trong mã của tôi có rất nhiều mã như:cách chuyển khối dưới dạng đối số của macro trong mục tiêu-c?

if (block) block(....) 

Vì vậy, tôi muốn xác định một macro, một cái gì đó giống như

#define safetyCall(block, ...) if((block)) {block(##__VA_ARGS__)}; 

Nhưng tôi không thể làm cho nó làm việc. Bất kỳ ý tưởng?

+0

nếu tôi gọi 'safetyCall (phương pháp, 0, newErr); 'biên dịch nói: "Dán hình thành '(0', một tiền xử lý thẻ không hợp lệ" và "mong đợi ';' sau khi biểu – jAckOdE

Trả lời

6

Bạn không cần ##; nhu cầu di chuyển:

#define safetyCall(block, ...) if((block)) { block(__VA_ARGS__); } 
+0

hoạt động hoàn hảo, cảm ơn rất nhiều! – jAckOdE

+0

btw, khác biệt giữa '__VA_ARGS__' và' ## __ VA_ARGS__' – jAckOdE

+1

@jAckOdE Mã thông báo '##' được sử dụng để "xâu chuỗi" đối số của nó (nghĩa là biến chúng từ 'x' thành' "x" ') – trojanfoe

2

này có thể chạy vào các vấn đề nếu khối của bạn là nội tuyến và có chứa mã mà có một loạt các dấu phẩy chuỗi tách vv

Ví dụ:.

safetyCall(^void() { 
    NSArray *foo = @[@"alice", "bob"]; 
}; 

Trình biên dịch sẽ phàn nàn về " '' mong đợi ']' hoặc" và "nhận dạng mong đợi hoặc '('"

Tuy nhiên, nếu bạn đã khai báo khối nội tuyến dưới dạng một khối riêng biệt trước macro, nó sẽ không tạo ra lỗi.

Ví dụ:

void (^fooBlock)(void) = ^void() { 
    NSArray *foo = @[@"alice", @"bob"]; 
} 

safetyCall(fooBlock); 
+0

hoặc chỉ quấn khối trong dấu ngoặc đơn – newacct

Các vấn đề liên quan