Rudolf Adamkovič
Rudolf Adamkovič

Reputation: 31486

Objective C Blocks - Syntax

I have a block defined like this:

CGPoint (^rotateOrderedPair)(CGFloat, CGFloat, CGFloat, CGFloat, CGFloat) = ^(CGFloat x, CGFloat y, CGFloat pivotX, CGFloat pivotY, CGFloat angle) {
    CGFloat rotatedX = cos(angle) * (x - pivotX) - sin(angle) * (y - pivotY) + pivotX;
    CGFloat rotatedY = sin(angle) * (x - pivotX) + cos(angle) * (y - pivotY) + pivotY;
    return CGPointMake(rotatedX, rotatedY);
};

I'd like to ask why in the world do I have to write (CGFloat, CGFloat, CGFloat, CGFloat, CGFloat) when there's a list of all the named arguments only a couple of characters later? Why such duplicity? I must be missing something obvious.

Upvotes: 2

Views: 126

Answers (2)

zoul
zoul

Reputation: 104125

People usually typedef any non-trivial block, which makes this almost a non-issue:

typedef CGPoint (^XYPointTransform)(CGFloat, CGFloat, CGFloat, CGFloat, CGFloat);

And then:

XYPointTransform rotateOrderedPair =
    ^(CGFloat x, CGFloat y, CGFloat pivotX, CGFloat pivotY, CGFloat angle) {
    // …
});

The typedef is also desirable from the point of code readability. Also, the signature in the declaration and definition doesn’t have to be exactly the same:

typedef void (^SomeBlock)(NSObject*);
SomeBlock foo = ^(id arg) {…};

This means that you’re not repeating exactly the same stuff twice and the possibility to pick a slightly different type in the actual block definition is sometimes handy.

I agree it would be nice to have some sort of type inference:

auto block = ^(/* a complex signature*/) {…};

This doesn’t exist, as far as I know.

Upvotes: 3

Monolo
Monolo

Reputation: 18253

The syntax of blocks is largely modeled on the syntax of C function pointers, so you should probably look for the rationale in that world.

Upvotes: 0

Related Questions