1

I got a snippet today,

self.tableView = ({
    CGRect frame = CGRectMake(0.f, 0.f, kBPNavigationBarClockInOutAssociatesTableViewWidth,
                              kBPNavigationBarClockInOutAssociatesTableViewHeight);
    UITableView * tableView =
        [[UITableView alloc] initWithFrame:frame style:UITableViewStylePlain];
    tableView.autoresizingMask = (UIViewAutoresizingFlexibleTopMargin
                                  |UIViewAutoresizingFlexibleBottomMargin
                                  |UIViewAutoresizingFlexibleWidth);
    tableView.delegate   = self;
    tableView.dataSource = self;

    [tableView setOpaque:NO];
    [tableView setScrollEnabled:YES];
    [tableView setBounces:YES];
    [tableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];
    [tableView setBackgroundView:nil];
    [tableView setBackgroundColor:[UIColor clearColor]];

    tableView;
});
  • 1st question:

The ({}) is interesting that it can run the wrapped codes in sync mode and return the object of tableView at the end of its content.

I just suppose it is a block here, however why it is not look like:

UITableView * (^testBlock) (void) = ^{ // Codes here... return tableView;};
UITableView *myTableView = testBlock();
  • 2nd question

The ({}) is not in async mode when I testing the code in Xcode, but in my experience, the block always (? also super junior question here: is block always running in async mode ?) runs in async mode. So why it is not here?

  • 3rd question

When I google the block syntax with return object, I find that all the block returns primitive value such as BOOL and Double, and not lucky enough to find one that return an object. Is this true that a block can only return a primitive value?

reviese:

I find this snippet in Why doesn't this rudimentary Objective C-block code work?:

NSString *(^print_block)() = ^{
    return @"this block worked!";  
};
NSLog(@"%@", print_block());

So I think a block can also return a object type.

Many thanks!

Community
  • 1
  • 1
Damon Yuan
  • 3,683
  • 4
  • 23
  • 31
  • See http://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html#Statement-Exprs (it's not a block). – par Oct 07 '14 at 04:25
  • Yes, it is a block. See https://developer.apple.com/library/ios/documentation/cocoa/conceptual/programmingwithobjectivec/WorkingwithBlocks/WorkingwithBlocks.html However, if you want it async, you need to play with Dispatch Queues with Grand Central Dispatch(see the bottom of the doc link) – Horst Oct 07 '14 at 04:45
  • 1
    @Horst - Blocks use a carat, e.g. `^{`. The syntax he's asking about `({})` is something entirely different. See the link I posted. – par Oct 07 '14 at 04:53

1 Answers1

3

I guess I'll make my comment an answer. It's not a block. It's a case of an interesting compiler/code mechanism in GCC/LLVM called "Statements and Declarations in Expressions."

It gives you the ability to execute an arbitrary block of code and have the very last statement be the return value to an assignment. So in your case the thing that gets returned is the very last line, tableview.

Personally, I think the way it has been used here is confusing. A function or just writing that code inline would probably have been better.

The use case for this (at least that I've found) is typically in developing preprocessor macros that execute some code with automatic variables and return their value, e.g.:

#define pow( _x ) ({ int x = (_x); x*x; })

Kind of a trivial example, and maybe not all that great because I'm assuming the value of _x is assignable to int, but you get the idea. Notice how in this macro _x is evaluated only once.

That's where I see the utility of this syntax primarily, vs. other types of macro evaluation.

par
  • 17,361
  • 4
  • 65
  • 80