2013-10-01 4 views
6

В моем коде я много кода, как:как передать блок как аргумент макроса в объективе-c?

if (block) block(....) 

Так что я хочу, чтобы определить макрос, что-то вроде

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

Но я не мог заставить его работать. Есть идеи?

+0

, если я называть 'safetyCall (метод, 0, newErr);' Компилятор сказать: "Склеивание формируется '(0', недействительный предварительной обработки маркера" и «Ожидаемые ';' после того, как выражение « – jAckOdE

ответ

6

Вам не нужны ## и ; потребности перемещения:

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

Работает отлично, спасибо! – jAckOdE

+0

btw, что между' __VA_ARGS__' и '## __ VA_ARGS__' и' ## __ VA_ARGS__' – jAckOdE

+1

@jAckOdE Символ '##' используется для «подражания» его аргументов (т. Е. Превратить их из 'x' в' «x» '). – trojanfoe

2

Это может столкнуться с проблемами, если ваш блок инлайн и содержит код, который содержит ряд строк, разделенных запятой и т.д.

Пример:.

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

компилятор будет жаловаться "" ожидаемый ']' или" и "ожидаемого идентификатора или '('"

Однако, если вы должны объявить встроенный блок как отдельный блок перед макросом, он не будет генерировать ошибку.

Пример:

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

safetyCall(fooBlock); 
+0

или просто оберните блок в круглые скобки – newacct

Смежные вопросы