是否可以使用单个typedef来定义一个不带参数并返回块的块



类似/跟进此问题:在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);

我错过了什么。。。

正确的语法是:

typedef void (^(^ComplexBlock)(void))(void);

当您构造这样复杂类型的声明时,从更简单的类型开始并用"表达式"代替标识符会有所帮助。

因此,例如,声明一个不带参数并返回void:的函数

void a_func(void);

现在,我们想要声明一个函数指针a_func_ptr,它是指向相同类型函数的指针。我们希望表达式*a_func_ptra_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);

最新更新