Написать макросы для вызовов GCD? - PullRequest
4 голосов
/ 24 февраля 2012

Я хотел бы создать макрос для вызовов GCD, например:

dispatch_async(dispatch_get_main_queue(), ^{
    stuff....
});

макрос может выглядеть примерно так: Основной (^ {...})

Не уверен, как это написать. Любое предложение?

спасибо

Ответы [ 2 ]

11 голосов
/ 24 февраля 2012

Предложение: не надо. Помимо всего прочего, он будет искажать номера строк при отладке.

Вы можете определить обычную функцию, которая будет делать то же самое, если хотите, что-то вроде

typedef void(^VoidBlock)();
void on_main(VoidBlock block) {
    dispatch_async(dispatch_get_main_queue(), block);
}

Это имеет то преимущество, что вы не теряете номера строк для блока во время отладки. Я даже делал такие вещи, как

void on_main(VoidBlock block) {
  if (dispatch_get_current_queue() == dispatch_get_main_queue()) {
    block();
  } else {
    dispatch_sync(dispatch_get_main_queue(), block);
  }
}

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

Вы действительно хотите избежать помещения блоков кода в аргументы макроса. Если вы делаете и должны отлаживать этот код, вы ненавидите себя. (Немного в щеке, но это действительно больно, если вам нужно отлаживать любой макрос, который расширяется до нескольких строк кода.)

3 голосов
/ 03 апреля 2012

Вы можете определить макросы следующим образом:

#define ASYNC(...) dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ __VA_ARGS__ })
#define ASYNC_MAIN(...) dispatch_async(dispatch_get_main_queue(), ^{ __VA_ARGS__ })

Первый вызовет код асинхронно в неопределенном потоке (с помощью него выполняют все долго выполняющиеся задачи), а второй вызовет блок асинхронно в главном потоке (с помощью него выполняют все связанные с пользовательским интерфейсом вещи).

Вы можете комбинировать оба. Допустим, вы хотите получить что-то из сети и обновить пользовательский интерфейс, вы можете написать:

ASYNC({
  NSString *result = [[NSString alloc] initWithContentsOfURL: ...];
  ASYNC_MAIN({
    self.myTextField.string = result;
    [result release];
  });
});

Вы добавляете фигурные скобки для правильного отступа кода Xcode.

Обратите внимание, где совершаются / удерживаются звонки. Это мощная техника, которая сделает ваш код читабельным.

...