2013-10-01 93 views
6

在我的代碼,我有很多這樣的代碼:如何將block作爲宏的參數傳遞給objective-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__'之間的差異 – 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