Функция, которая возвращает функцию - PullRequest
4 голосов
/ 13 июля 2011

Как назначить и впоследствии вызвать функцию, которая возвращает функцию к локальной переменной в Objective-C?

ОБНОВЛЕНИЕ:

Я придумал следующее, но это все еще неХорошо, я боюсь:

(void (^)()) (^loadedCallback) () = (void (^)()) ^(){
    @synchronized (synchronizer) {
        semaphore++;
    }
      return Block_copy(^{
          @synchronized (synchronizer) {
              semaphore--;
              if (semaphore == 0) {
                  onAllLoaded();
              }
          }
      }); };

1 Ответ

5 голосов
/ 13 июля 2011

Во-первых, вам нужно понять синтаксис объявления указателя функции . То же самое для блоков, за исключением того, что это ^ вместо *.

Затем вам нужно создать блок и вернуть копию его и присвоить его правильно объявленной переменной.

typedef NSArray* (^my_block_type_t)(int, float);

my_block_type_t createBlock()
{
    my_block_type_t block = ^(int a, float b)
    {
        return [NSArray array];
    };
    return Block_copy(block);
}

/* snip */
my_block_type_t theBlock = createBlock();
theBlock();
Block_release(theBlock);

РЕДАКТИРОВАТЬ для редактирования ОР: typedef s обычно используются для облегчения чтения кода. В случае блоков и указателей на функции это также облегчает написание. Существует встроенный typedef (dispatch_block_t) для блоков, которые не принимают аргументов и возвращают void; Вы должны использовать это. Вы также должны сделать столько typedefs, сколько вам нужно, чтобы избежать необходимости использовать указатели на синтаксическую функцию уродливого объявления, иначе вынудите ваш код.

typedef dispatch_block_t (^block_creator_t)();

block_creator_t loadedCallback = ^{
    @synchronized (synchronizer)
    {
        semaphore++;
    }

    dispatch_block_t result = ^{
        @synchronized (synchronizer)
        {
            semaphore--;
            if (semaphore == 0)
                onAllLoaded();
        }
    };

    return Block_copy(result);
};
...