类似/跟进此问题: Syntax to define a Block that takes a Block and returns a Block in Objective-C
我知道这不是我想要做的,但是我想了解为什么我不能使用单个typedef来定义:
typedef void (^XYZSimpleBlock)(void);
typedef XYZSimpleBlock (^ComplexBlock)(void);
为什么上述方法有效,但这无效?
typedef void(^)(void) (^ComplexBlock)(void);
如果我得到类似的答案,我发现我可以像编译器一样尝试解析它,但是我是一个不好的编译器。
遵循C的左右规则,第一个标识符不是ComplexBlock
吗?
typedef void(^)(void) (^ComplexBlock)(void);
// parser reads left right and finds ComplexBlock first
然后它将右移并找到声明的结尾,然后向左移直到找到插入符,然后向右解释参数列表。
那把我们带到了
typedef void(^)(void) (^ComplexBlock)(void);
// | unhandled |compiled/interpreted|
这时发生了什么情况,它无法将void(^)(void)
读取为返回类型?
让我感到困惑的是,使用typedef基本上只是一个#define
,所以它不应该与上面基本相同吗?
typedef void (^XYZSimpleBlock)(void);
same as:
void(^)(void)
so:
typedef XYZSimpleBlock (^ComplexBlock)(void);
should be the same as:
typedef void(^)(void) (^ComplexBlock)(void);
我在这里想念东西...
答案 0 :(得分:3)
正确的语法是:
typedef void (^(^ComplexBlock)(void))(void);
像这样构造复杂类型的声明时,它可以帮助从更简单的类型开始,并将“表达式”替换为标识符。
例如,声明一个不带任何参数并返回void
的函数:
void a_func(void);
现在,我们要声明一个函数指针a_func_ptr
,它是指向相同类型函数的指针。我们希望表达式*a_func_ptr
与a_func
具有相同的类型,因此我们将该表达式放在括号中,并放到上面并得到:
void (*a_func_ptr)(void);
如果要使用块指针而不是函数指针,请使用^
代替*
:
void (^a_block_ref)(void);
(人们发现块语法令人沮丧的一个原因是,人们从未真正写过表达式^a_block_ref
来“解引用”一个块变量,因此这种跨越是不明显的。)
采用上述方法并在其中typedef
(而不是变量声明)中,您将获得:
typedef void (^XYZSimpleBlock)(void);
但是,暂时让我们回到函数指针a_func_ptr
。假设您想声明一个返回函数指针的函数func_returns_func
。您将函数调用表达式放在a_func_ptr
所在的位置。也就是说,您将func_returns_func()
放入:
void (*func_returns_func())(void);
现在,在声明函数时,您无需使用void
而不使用参数,因此您可以这样做:
void (*func_returns_func(void))(void);
请注意,您不会在标识符左侧收集或隔离返回类型。它围绕标识符。
现在,将*
更改为^
,以获得返回块引用而不是函数指针的函数:
void (^func_returns_block(void))(void);
我们创建一个指向返回块引用的函数的指针。将(*ptr_to_func_returns_block)
放入func_returns_block
并获得:
void (^(*ptr_to_func_returns_block)(void))(void);
再次,将*
替换为^
,以获得对块的引用,该块返回一个块引用:
void (^(^block_returns_block)(void))(void);
我们在那里。只需更改名称,即可获得:
void (^(^ComplexBlock)(void))(void);