Objective-C синтаксис блока - может кто-нибудь объяснить это?

Может ли кто-нибудь объяснить, как работает этот синтаксис блока?

AStreamBuilder stream_builder = [ [ ^( void )
   {
      // some more code..  
      return (NSInputStream *)[ NSInputStream inputStreamWithFileAtPath: some_path ];
   } copy ] autorelease ];
   return stream_builder;

Какое название блока здесь? Почему блок копируется и затем автореализован? Я немного смущен тем, что происходит здесь. Блок, как говорят, возвращает AStreamBuilder, но внутри тела блока он возвращает экземпляр NSInputStream.

Может ли кто-нибудь сломать это?

Ответ 1

Это блок:

^( void )
   {
      // some more code..  
      return (NSInputStream *)[ NSInputStream inputStreamWithFileAtPath: some_path ];
   }

он не получает никакого параметра (следовательно, (void)) и возвращает экземпляр NSInputStream. Обратите внимание, что у него нет "имени" в том же смысле, что, например:

[[NSNumber alloc] initWithInt:42];

не имеет имени.

Поскольку в стеке создаются блоки, если вам нужно вернуть блок, вы должны скопировать его из стека в кучу (следовательно, -copy). Это находящийся в собственности объект; для возврата объекта, который не принадлежит вызывающему, блок автореализован (следовательно, -autorelease):

[ [ ^( void )
   {
      // some more code..  
      return (NSInputStream *)[ NSInputStream inputStreamWithFileAtPath: some_path ];
   } copy ] autorelease ];

Таким образом, выдержка выше - это автореализованный блок, который был скопирован из стека в кучу. Он присваивается переменной

AStreamBuilder stream_builder = …

поэтому вероятность того, что AStreamBuilder будет typedef для блока, который не получает никаких параметров и имеет тип возврата NSInputStream (или совместимый с ним тип). Обратите внимание, что AStreamBuilder является типом блока, а не типом значения, возвращаемого блоком. Что-то вроде:

typedef NSInputStream * (^AStreamBuilder)(void);

Ответ 2

Какое имя этого блока здесь?

Новый блок присваивается переменной stream_builder. У него нет имени как такового, так как блок является " анонимной встроенной коллекцией кода"

Почему блок копируется и затем автореализован?

Потому что он будет поддерживаться после текущей области (он возвращается из метода/функции). Поэтому он должен быть скопирован в кучу.

говорится, что блок возвращает AStreamBuilder, но внутри тела блока он возвращает экземпляр NSInputStream

Функция/метод, в котором вы находитесь (тот, который заканчивается на return stream_builder;), возвращает AStreamBuilder (= вновь созданный блок). Сам блок вернет NSStream, когда вызывается в какой-то момент в будущем.

Ответ 3

Блок копируется, чтобы переместить его из стека в кучу. Это необходимо, если вы хотите использовать блок за пределами области, в которой вы его создаете.