函数返回block时候值得注意
Block type variables
As we’ve learned, a Block literal looks the same as a function definition except it has no name and it has the “^” symbol. For the C function, the address of the function can be assigned to a variable of the function pointer type.
int func(int count)
{
return count + 1;
}
int (*funcptr)(int) = &func;
In the example, the address of function “func” is assigned to a variable “funcptr”.
In a similar manner, a Block literal can be assigned to a Block-type variable, which means that when a Block literal is in source code, a value is generated. The value can be assigned to a variable of the Block type. In Blocks, the generated value is called Block as well. “Block” is used both for a Block literal itself in a source code and the value generated from the Block literal. Next, let’s see how to declare Block-type variables.
int (^blk)(int);
If you compare the previous source code of a function pointer, you will see that the variable declaration of the Block type is the same as that of the function pointer type except for “*” and “^”. Just as with normal C variable types, this declaration can be used for:
- Automatic variables
- Function arguments
- Static variables
- Static global variables
- Global variables
Next, let’s see how you can assign a Block to the variable from a Block literal.
int (^blk)(int) = ^(int count){return count + 1;};
A Block is generated from the Block literal starting with “^”. And the Block is assigned to the variable “blk”. Of course you can assign the value to other variables of the Block type.
int (^blk1)(int) = blk;
int (^blk2)(int);
blk2 = blk1;
Functions can take arguments of Block type.
void func(int (^blk)(int))
{
Also, functions can return a Block.
int (^func()(int)) {
return ^(int count){return count + 1;};
}
As you’ve seen, source code with a Block type becomes complex, especially when it is used for function arguments or its return type. You can avoid the complexity by using typedef as is done for function pointers.
typedef int (^blk_t)(int);
With this typedef, you can declare variables of “blk_t” type. So, the previous source code can be modified as follows.
/* original
void func(int (^blk)(int))
*/
void func(blk_t blk)
{
/* original
int (^func()(int))
*/
blk_t func()
{
With the typedef, the function definitions become very simple.
Incidentally, you can execute a Block, which is assigned in a variable, the same way you call a function and you can execute the Block in almost the same way as calling a function that is assigned to a variable. A variable “funcptr” of a function pointer type is called as
int result = (*funcptr)(10);
A variable “blk” of a Block type can be called as
As you see, you can call a Block-type variable in exactly the same way as a C function. The next example shows how to execute a Block, which is passed by the argument of a function.
int func(blk_t blk, int rate)
{
return blk(rate);
}
Of course, a Block can be used with the Objective-C method as well.
- (int) methodUsingBlock:(blk_t)blk rate:(int)rate {
return blk(rate);
}
You can use Block-type variables in the same way as variables in C. You can also use a pointer to Block-type variables, meaning that you can use variables of Block pointer type.
typedef int (^blk_t)(int);
blk_t blk = ^(int count){return count + 1;};
blk_t *blkptr = &blk;
(*blkptr)(10);