Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Casting nil in block

I was just quickly playing with blocks today and I came across the error:

NSString *(^testBlock)(int) = ^(int option) {
    if (option == 1) return @"ONE";
    if (option == 2) return @"TWO";
    return nil;
};
NSLog(@"OUTPUT: %@", testBlock(4));
Return type 'void *' must match previous return type 'NSString *' when block literal has unspecified explicit return type

As I really wanted to return nil if "1" or "2" were not input I decided to simply cast the final return back to an NSString using:

NSString *(^testBlock)(int) = ^(int option) {
    if (option == 1) return @"ONE";
    if (option == 2) return @"TWO";
    return (NSString *) nil;
};

This works just fine, I was just curious if this was the correct solution or even bad practice as I have never thought about casting nil before?

like image 323
fuzzygoat Avatar asked Jan 10 '13 13:01

fuzzygoat


1 Answers

It's not the best approach.

You should correct the first line to this:

NSString *(^testBlock)(int) =  ^NSString*(int option){
    if(option == 1) return @"ONE"; 
    if(option==2) return @"TWO";
    return nil;
};

This way the block literal has the return type specified and the error goes away. Correctly.

EDIT: Adding explanation on the initial error:

A block without a return type will have the return type inferred by the compiler (which doesn't happen with functions). When you have 2 return statements in the block with different types (note that nil is void*) the compiler can't infer the return type and reports an error. To fix that error you have to manually specify a return type to avoid ambiguity for the compiler.

As a good practice, never return different types from the same block unless you are using polymorphism.

like image 125
sqreept Avatar answered Oct 20 '22 01:10

sqreept