Правильный синтаксис:
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);