chm
chm

Reputation: 1519

Objective-C block parameters

Say we have this block:

int (^aBlock)(BOOL) = ^(BOOL param) { ...

My current understanding of this is: the first int is the return type, (^aBlock)(BOOL) gives the name of the method and the type of its parameter, and = ^(BOOL param) is the parameter's name inside the block ... plus the parameter's type again?

Why is the syntax such that we have to list the parameter type twice? Could the two types ever be different?

Upvotes: 12

Views: 5783

Answers (4)

Rajkumar Yadav
Rajkumar Yadav

Reputation: 81

According to Ry's Objective C Tutorial:

Blocks use all the same mechanics as normal functions. You can declare a block variable just like you would declare a function.

 NSInteger (^BlocksAddition)(NSInteger x,NSInteger y)=^NSInteger(NSInteger x, NSInteger y){

    return x+y;
};

NSUInteger result=BlocksAddition(4,5);
NSLog(@"Addition Result:%d",result);

Upvotes: 0

Carl Veazey
Carl Veazey

Reputation: 18363

It is not quite "listing the parameter type twice", you are in the first case declaring the type of a block variable, and in the second case you are defining a block literal. Then you are assigning the literal to the value of the variable. You could even do something like this, which is equivalent and better illustrates the fact that these are really two totally independent declarations, despite being associated with an assign statement:

id thisBlock = ^id (id x, NSUInteger idx) {
    NSLog(@"x = %@",x);
    return x;
};

id (^thatBlock)(id obj, NSUInteger index) = thisBlock;

The fact that they are independent of each other means it's probably not even correct to attempt to provide some kind of transference or inheritance of typing information from the left hand side of the expression to the right. And yes, the types can be different - consider this code compiles and executes just fine:

id (^thatBlock)(NSArray *, NSDictionary *, NSString *) = ^id (id x, id y, id z) {
    NSLog(@"x = %@",x);
    return x;
};

thatBlock(@[],@{},@"");

Hope this helps!

Upvotes: 13

benzado
benzado

Reputation: 84388

The code snippet you have given isn't a block declaration: it's a block declaration and a block definition. First, you declare an identifier named aBlock:

int (^aBlock)(BOOL)

then you define a block:

^(BOOL param) { ...

Both of these are parsed and evaluated separately. Since you are assigning one to the other, the compiler does a type-check to make sure that the expression on the left hand side (your aBlock declaration) is of the same type as the expression on the right hand side (the block definition).

So, the answer is, these parts need to be evaluated separately. Since the block definition is being compiled on its own, you have to include the type of param, because otherwise the compiler won't know what type it should be. (Yes, you could make an exception in this case, and look across the assignment, but everywhere else in the C language you declare an identifier by giving a type first, so why do it differently here?)

But -- you may say -- if that's true why didn't I have to define the return type (int) on the right-hand side?

Very astute of you. The answer is that, when writing a block expression, you don't need to define the return type, because the compiler can infer it from the return statement (or lack thereof) inside the block.

(So why do you have to include return types with function definitions? Well, history, I guess. Programming language definitions were created by imperfect humans.)

Upvotes: 2

Kjuly
Kjuly

Reputation: 35181

Why is the syntax such that we have to list the parameter type twice?

The block is designed in this way, and so you can do it like this:

int (^aBlock)(BOOL);

aBlock = ^(BOOL param) {
  ...
};

It just likes

- (int)aMethodWithParam:(BOOL)param;

- (int)aMethodWithParam:(BOOL)param {
  ...
}

Could the two types ever be different?

Nope, and what's more, the order of the types should be the same, i.e.:

int (^aBlock)(BOOL, NSString*) = ^(BOOL param, NSString *aString) {
  ...
};

And here's a clear figure for block:

Image

Upvotes: 5

Related Questions