Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to pass block as a macro's argument in objective-c?

In my code i have a lot of code like:

if (block) block(....)

So I want to define a macro, something like

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

But i couldn't get it to work. Any idea?

like image 762
jAckOdE Avatar asked Oct 01 '13 06:10

jAckOdE


Video Answer


2 Answers

You don't need the ## and the ; needs moving:

#define safetyCall(block, ...) if((block)) { block(__VA_ARGS__); }
like image 167
trojanfoe Avatar answered Nov 01 '22 00:11

trojanfoe


This can run into issues if your block is inline and contains code that has a series of comma separated strings, etc.

Example:

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

The compiler will complain about "Expected ']' or '.'" and "Expected identifier or '('".

However, if you were to declare the inline block as a separate block before the macro, it will not generate an error.

Example:

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

safetyCall(fooBlock);
like image 44
Ari Braginsky Avatar answered Nov 01 '22 02:11

Ari Braginsky